package com.egoo.ticket.server.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.egoo.ticket.server.config.mq.MqCommonUtil;
import com.egoo.ticket.server.dao.*;
import com.egoo.ticket.server.pojo.dto.*;
import com.egoo.ticket.server.pojo.entity.*;
import com.egoo.ticket.server.pojo.enums.FieldEnum;
import com.egoo.ticket.server.pojo.vo.*;
import com.egoo.ticket.server.project.ProjectConstant;
import com.egoo.ticket.server.project.jincheng.JinChengBaseUtil;
import com.egoo.ticket.server.project.sunong.SuNongBaseUtil;
import com.egoo.ticket.server.project.zheneng.ZheNengBaseUtil;
import com.egoo.ticket.server.service.*;
import com.egoo.ticket.server.utils.activiti.ActCommonUtils;
import com.egoo.ticket.server.utils.activiti.ActTaskServiceUtil;
import com.egoo.ticket.server.utils.common.*;
import com.egoo.ticket.server.utils.common.ConstantCode.*;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.CollectionUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Administrator
 */
@Service
@Slf4j
//@Transactional(rollbackFor = Exception.class)
public class WorkOrderServiceImpl implements WorkOrderService {
	@Autowired
	private CreateCodeUtil createCodeUtil;
	@Autowired
	private WorkOrderDao workOrderDao;
	@Autowired
	private EwsUserDao ewsUserDao;
	@Autowired
	private WorkOrderFilterMenuService workOrderFilterMenuService;
	@Autowired
	private WorkOrderTypeDao workOrderTypeDao;
	@Autowired
	private WorkOrderStatusDao workOrderStatusDao;
	@Autowired
	private WorkOrderTypeNodeDao workOrderTypeNodeDao;
	@Autowired
	private FormTemplateDao formTemplateDao;
	@Autowired
	private EwsUserRoleDao ewsUserRoleDao;
	@Autowired
	private TaskTimeOutRecordDao taskTimeOutRecordDao;
	@Autowired
	private WorkOrderLogDao workOrderLogDao;
	@Autowired
	private EripDataSynService eripDataSynService;
	@Autowired
	private WorkOrderLogService workOrderLogService;
	@Autowired
	private ExternalFlowInfoDao externalFlowInfoDao;
	@Autowired
	private WorkOrderFilterMenuDao workOrderFilterMenuDao;
	@Autowired
	private UserService userService;
	@Autowired
	private EwsDepartmentDao ewsDepartmentDao;
	@Autowired
	CommonUtil commonUtil;
	@Autowired
	DynamicSqlJoinUtil dynamicSqlJoinUtil;
	@Autowired
	TaskSignInService taskSignInService;
	@Autowired
	private WorkOrderRelationMapper workOrderRelationMapper;
	@Autowired
	private WorkOrderFieldReflectDao workOrderFieldReflectDao;
	@Autowired
	private SysDictDao sysDictDao;
	@Autowired
	private HeadFieldMapper tableHeadFieldMapper;
	@Autowired
	private TaskFormDao taskFormDao;

	// 文件服务器路径
	@Value("${server.file-server-url}")
	private String fileServerUrl;
	// fileserver https请求地址
	@Value("${fileserver.url-https}")
	private String fileServerHttpsUrl;
	@Autowired
	private RestTemplate restTemplate;
	@Autowired
	private HeadFieldService headFieldService;
	@Autowired
	private CustomFieldService customFieldService;
	@Autowired
	private HeadFieldMapper headFieldMapper;
	@Value("${server.project-sign}")
	private String projectSign;
	@Autowired
	private SuNongBaseUtil suNongBaseUtil;
	@Autowired
	private JinChengBaseUtil jinChengBaseUtil;
	@Autowired
	private ZheNengBaseUtil zheNengBaseUtil;
	@Autowired
	private WorkOrderTypeService workOrderTypeService;
	@Autowired
	private MqCommonUtil mqCommonUtil;

	// 工单前端页面请求地址
	@Value("${order.front.url}")
	private String orderFrontUrl;

	// 工单详情页面路由
	@Value("${order.front.detail-routre}")
	private String detailRoutre;

	@Autowired
	private HandleSqlInjectionUtil handleSqlInjectionUtil;

	public static SimpleDateFormat sdfTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	/**
	 * TODO 创建工单
	 * @author: victor_tang
	 * @createtime: 2020/5/25 10:58
	 * @param workOrderDto 1
	 * @return: com.egoo.ticket.server.utils.common.DbResponse
	 */
	@Override
	public DbResponse create(WorkOrderDto workOrderDto) {
		// 获取当前用户信息
		EwsUser ewsUser = ewsUserDao.selectById(workOrderDto.getUserId());
		WorkOrder workOrder = new WorkOrder();
		// 根据操作类型设置工单状态
		workOrder = setWorkOrderStateByOptionType(workOrder,workOrderDto,ewsUser);

		// 启动activiti流程
		ActiviVo activiVo = createProcessInstanceByWorkOrderType(workOrderDto);
		// 设置流程实例id
		workOrder.setProcessInstanceId(activiVo.getProcessInstId());

		// 创建任务表单信息
		createOrUpdateFormTemplate(ewsUser,activiVo.getProcessInstId(), activiVo.getTaskId(),
				workOrderDto, workOrder.getStatusId());

		// 组装工单基础字段信息
		workOrder = addWorkOrderInfo(workOrder, workOrderDto);

		//组装工单关系表信息
		WorkOrderRelation workOrderRelation = addWorkOrderRelation(workOrderDto);
		workOrderRelation.setWorkOrderId(workOrder.getId());
		if (ProjectConstant.ProjectSign.ZHENENG.equals(projectSign) && WorkOrderProcessButton.FLOW_OUT.equals(workOrderDto.getOpration().getString("type"))) {
			workOrderRelation.setExternalWorkOrderId("QMT"+workOrder.getId());
		}

		// 根据操作类型设置工单信息
		workOrder = setWorkOrderInfoByOptionType(workOrder,workOrderDto,
				ewsUser,workOrderRelation);
		if (ProjectConstant.ProjectSign.ZHENENG.equals(projectSign) && WorkOrderProcessButton.FLOW_OUT.equals(workOrderDto.getOpration().getString("type"))) {
			if ("0".equals(workOrder.getChengRanResultSign())){
				JSONObject customField = workOrder.getCustomField();
				customField.put("APP_NO",workOrder.getAppNo());
				workOrder.setCustomField(customField);
				log.info("customFied中存的数据:"+customField);
			}else if (StringUtils.isEmpty(workOrder.getChengRanResultSign())){

			}
			else {
				return new DbResponse(ResponseConstant.RES_FAIL_CODE,"创建失败:"+workOrder.getFailDescription());

			}
		}
		//合并工单
		if (!StringUtils.isEmpty(workOrderDto.getCombineWorkOrderIds())) {
			workOrderRelation.setMergeBaseWorkOrderIds(workOrderDto.getCombineWorkOrderIds());
			combineWorkOrderHandle(workOrderDto);
			setIsChildren(workOrderDto);
		}
		// 创建关联工单
		createConcatWorkOrder(workOrder.getId(), workOrderDto.getConcatWorkOrderId());
		// 创建工单
		workOrderDao.create(workOrder);
		// 创建工单关联关系
		workOrderRelationMapper.insertWorkOrderRelation(workOrderRelation);
		// 记录处理日志
		recordHandleLog(workOrder, ewsUser.getId(), workOrderDto.getOpration(),workOrderDto.getWriteFormTemplateInputDto());
		if (ProjectConstant.ProjectSign.ZHENENG.equals(projectSign)
				&& WorkOrderProcessButton.FLOW_OUT.equals(workOrderDto.getOpration().getString("type"))) {
			try {
				// 推送工单信息至ERIP的浙能CRM系统adapter
				pushWorkOrderInfo(workOrder, workOrderRelation);
			} catch (Exception e) {
				e.printStackTrace();
				log.info("浙能推送工单信息异常:"+e);
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				return new DbResponse(ResponseConstant.RES_FAIL_CODE,"创建工单失败");
			}
		}
		log.info("创建之后的工单create: {}", workOrder);
		// 给redis发布消息,为触发器执行准备
		if (workOrder.getIsPubRedisTopic()) {
			mqCommonUtil.pushToMsgTriggerQueue(workOrder.getId());
			mqCommonUtil.pushToMsgGeneralQueue(MsgNotifyType.FLOW_NOTIFY,workOrder.getId());
		}
		return new DbResponse(ResponseConstant.RES_SUCCESS_CODE, "新建成功！",workOrder.getId());
	}

	/**
	 * @Author: Donny_dong
	 * @Description:推送工单信息给浙能
	 * @Param:
	 * @return:
	 * @Date: 2020/11/25
	 * @param workOrder
	 * @param workOrderRelation
	 */
	private JSONObject pushWorkOrderInfo(WorkOrder workOrder,
								 WorkOrderRelation workOrderRelation) {
//		JSONObject customField = workOrder.getCustomField();
		String appNo = "";
		if (!Objects.isNull(workOrder.getAppNo())){
//			appNo = customField.getString("APP_NO");
			appNo = workOrder.getAppNo();
		}

		JSONObject jsonObject = new JSONObject();
		jsonObject.put("orderid",appNo);
		jsonObject.put("sessionid",workOrderRelation.getSessionId());
		return eripDataSynService.pushWorkOrderInfo(jsonObject);
	}

	/**
	 * @Author: Donny_dong
	 * @Description: 设置子工单标识
	 * @Param:
	 * @return:
	 * @Date: 2020/6/8
	 */
	private void setIsChildren(WorkOrderDto workOrderDto) {
		String combineWorkOrderIds = workOrderDto.getCombineWorkOrderIds();
		List<String> workOderIds = Arrays.asList(combineWorkOrderIds.split(","));
		for (String workOrderId:workOderIds
			 ) {
			WorkOrderRelation workOrderRelation = new WorkOrderRelation();
			workOrderRelation.setWorkOrderId(workOrderId);
			workOrderRelation.setIsChildren(IsChildren.IS_CHILDREN);
			workOrderRelationMapper.updateByNotPrimary(workOrderRelation);
		}
	}

	/**
	 * TODO 根据工单类型创建流程实例
	 * @author: victor_tang
	 * @createtime: 2020/5/25 10:49
	 * @param workOrderDto 1
	 * @return: com.egoo.ticket.server.pojo.vo.ActiviVo
	 */
	private ActiviVo createProcessInstanceByWorkOrderType(WorkOrderDto workOrderDto) {
		Long workOrderTypeId = workOrderDto.getWorkOrderTypeId();
		String workOrderTypeName = workOrderTypeDao.selectById(workOrderTypeId).getName();
		return ActCommonUtils.startProcessInstance("_" + workOrderTypeName + workOrderTypeId, workOrderDto.getUserId());
	}

	/**
	 * TODO 根据操作类型设置工单状态
	 * @author: victor_tang
	 * @createtime: 2020/5/25 10:40
	 * @param workOrder 1
	 * @param workOrderDto 2
	 * @param ewsUser 3
	 * @return: com.egoo.ews.service.pojo.entity.WorkOrder
	 */
	private WorkOrder setWorkOrderStateByOptionType(WorkOrder workOrder, WorkOrderDto workOrderDto, EwsUser ewsUser) {
		JSONObject optation = workOrderDto.getOpration();
		Integer statusId = Integer.parseInt(optation.getString("status"));
		// 操作后状态设的为状态不变
		if (WorkOrderState.NO_CHANGE == statusId &&workOrder.getStatusId()!=null) {
			statusId = workOrder.getStatusId();
		}
		if (ConstantCode.WorkOrderState.ALREDAY_CLOSE == statusId
				|| ConstantCode.WorkOrderState.ALREAAY_CASE == statusId
		) {
			workOrder.setCloseUserId(ewsUser.getId());
			workOrder.setCloseUserName(ewsUser.getName());
			workOrder.setCloseTime(new Timestamp(System.currentTimeMillis()));
		}
		workOrder.setStatusId(statusId);
		return workOrder;
	}

	/**
	 * TODO 根据操作类型设置工单信息
	 * @author: victor_tang
	 * @createtime: 2020/5/25 10:30
	 * @param workOrder 1
	 * @param workOrderDto 2
	 * @param ewsUser 3
	 * @param workOrderRelation 4
	 * @return: com.egoo.ews.service.pojo.entity.WorkOrder
	 */
	private WorkOrder setWorkOrderInfoByOptionType(WorkOrder workOrder,WorkOrderDto workOrderDto
			,EwsUser ewsUser,WorkOrderRelation workOrderRelation) {
		// 默认设置为true
		workOrder.setIsPubRedisTopic(true);
		// 判断动作类型
		JSONObject optation = workOrderDto.getOpration();
		String oprationType = optation.getString("type");
		Long workOrderTypeId = workOrderDto.getWorkOrderTypeId();
		log.info("传入的类型id为："+workOrderTypeId);
		WorkOrderTypeNodeVo workOrderTypeStartNodeVo = workOrderTypeNodeDao.selectStartNodeByWorkOrderTypeId(workOrderTypeId);
		if (ConstantCode.WorkOrderProcessButton.SAVE.equals(oprationType)) {
			// 保存按钮操作
			workOrder.setCurrentHandlerId(ewsUser.getId());
			workOrder.setCurrentHandlerName(ewsUser.getName());
			workOrder.setCurrentWorkOrderNodeId(workOrderTypeStartNodeVo.getId());
			workOrder.setCurrentWorkOrderNodeName(workOrderTypeStartNodeVo.getName());
			workOrder.setIsPubRedisTopic(false);
		} else if (ConstantCode.WorkOrderProcessButton.END.equals(oprationType)) {
			// 结束按钮操作
			workOrder.setCurrentHandlerId(ewsUser.getId());
			workOrder.setCurrentHandlerName(ewsUser.getName());
			workOrder.setHistoryHandlerId(ewsUser.getId());
			workOrder.setHistoryHandlerName(ewsUser.getName());
			workOrder.setCurrentWorkOrderNodeId(workOrderTypeStartNodeVo.getId());
			workOrder.setCurrentWorkOrderNodeName(workOrderTypeStartNodeVo.getName());
			workOrder.setCloseUserId(ewsUser.getId());
			workOrder.setCloseUserName(ewsUser.getName());
			workOrder.setCloseTime(new Timestamp(System.currentTimeMillis()));
		} else if (ConstantCode.WorkOrderProcessButton.JUMP.equals(oprationType)) {
			// 跳转按钮操作
			Long targetRefNodeId = Long.parseLong(optation.getString("targetRef"));
			WorkOrderTypeNodeVo workOrderTypeNodeVo = workOrderTypeNodeDao.getNodeByWorkOrderNodeId(targetRefNodeId);
			workOrder.setCurrentWorkOrderNodeId(targetRefNodeId);
			workOrder.setCurrentWorkOrderNodeName(workOrderTypeNodeVo.getName());
			// activiti的任意跳转
			ActCommonUtils.arbitraryJump(workOrderTypeNodeVo.getName() + targetRefNodeId, workOrder.getProcessInstanceId());
			workOrder = setTiaoZhuanWorkOrderHandlePersonInfo(workOrder, workOrderTypeNodeVo);
			// 记录正在运行任务信息，为节点和工单超时提供计算原始数据
			addTaskTimeOutRecordInfo(workOrder, targetRefNodeId.toString());

		} else if (ConstantCode.WorkOrderProcessButton.DISTRIBUTE.equals(oprationType)) {
			// 转派按钮操作
			Redeploy redeploy = workOrderDto.getRedeploy();
			Long targetNodeId = redeploy.getTargetNodeId();
			String targetNodeName = workOrderTypeNodeDao.getNodeByWorkOrderNodeId(targetNodeId).getName();
			workOrder.setCurrentWorkOrderNodeId(targetNodeId);
			workOrder.setCurrentWorkOrderNodeName(targetNodeName);
			workOrderRelation.setRedeployCount(1);
			// 设置当前工单处理人信息
			workOrder = setZhuanPaiWorkOrderHandlePersonInfo(workOrder, redeploy);
			// activiti的任意跳转
			ActCommonUtils.arbitraryJump(targetNodeName + targetNodeId,
					workOrder.getProcessInstanceId());
			// 记录正在运行任务信息，为节点和工单超时提供计算原始数据
			addTaskTimeOutRecordInfo(workOrder, targetNodeId.toString());
		}else if (WorkOrderProcessButton.FLOW_OUT.equals(oprationType)){
			try {
				workOrder = this.flowOutHandle(optation, workOrderDto, workOrder,workOrderRelation);
			} catch (Exception e) {
				log.error("转出工单异常"+e);
				workOrder =null;
			}
		}
		return workOrder;
	}


	/**
	 * @Author: Donny_dong
	 * @Description: 处理被合并的工单
	 * @Param:
	 * @return:
	 * @Date:
	 */
	private Integer handleMergedWorkOrderRelation(WorkOrder workOrder, WorkOrderDto workOrderDto) {
		String combineWorkOrderIds = workOrderDto.getCombineWorkOrderIds();
		if (StringUtils.isEmpty(combineWorkOrderIds)) {
			log.info("被合并工单的id为空");
			return null;
		}
		Integer integer = 0;
		List<String> ids = Arrays.asList(combineWorkOrderIds.split(","));
		HashMap<String, Object> hashMap = new HashMap<>(2);
		hashMap.put("workOrderIds", ids);
		List<WorkOrderRelation> workOrderRelations = workOrderRelationMapper.selectWorkOrderRelations(hashMap);
		for (WorkOrderRelation workOrderRelation : workOrderRelations) {
			workOrderRelation.setMergeBaseWorkOrderIds(workOrder.getId());
			integer += workOrderRelationMapper.updateWorkOrderRelation(workOrderRelation);
		}

		return integer;

	}

	/**
	 * @Author: Donny_dong
	 * @Description: 组装工单关联关数据
	 * @Param:
	 * @return:
	 * @Date: 2020/4/24
	 */
	private WorkOrderRelation addWorkOrderRelation(WorkOrderDto workOrderDto) {
		WorkOrderRelation workOrderRelation = new WorkOrderRelation();
		if (workOrderDto.getConcatWorkOrderId() != null) {
			workOrderRelation.setConcatWorkOrderIdStr(workOrderDto.getConcatWorkOrderId());
		} else {
			workOrderRelation.setConcatWorkOrderIdStr("");
		}
		workOrderRelation.setUrgeCount(0);
		workOrderRelation.setRedeployCount(0);
		workOrderRelation.setSessionId(workOrderDto.getVoiceKeyId());
		workOrderRelation.setId(createCodeUtil.getWorkOrderRelationId());
		workOrderRelation.setIsChildren(IsChildren.NON_CHILDREN);
		workOrderRelation.setIsTimeOut(ConstantCode.N);
		return workOrderRelation;

	}

	/**
	 * @return void
	 * @Author Donny_Dong
	 * @Description //TODO 处理合并的工单
	 * @Date 11:30 2020/2/4
	 * @Param [workOrderDto]
	 **/
	private void combineWorkOrderHandle(WorkOrderDto workOrderDto) {
		String combineWorkOrderIds = workOrderDto.getCombineWorkOrderIds();
		List<String> idList = Arrays.asList(combineWorkOrderIds.split(","));
		String userId = workOrderDto.getUserId();
		EwsUser ewsUser = ewsUserDao.selectById(userId);
		ArrayList<WorkOrder> workOrderList = new ArrayList<>();
		for (String id : idList) {
			WorkOrder workOrder = workOrderDao.selectById(id);
			workOrder.setLastUserId(userId);
			workOrder.setLastUserName(ewsUser.getName());
			workOrder.setCloseUserId(userId);
			workOrder.setCloseUserName(ewsUser.getName());
			workOrder.setHistoryHandlerId(workOrder.getHistoryHandlerId() + "," + userId);
			workOrder.setHistoryHandlerName(workOrder.getHistoryHandlerName() + "," + ewsUser.getUserName());
			Timestamp time = new Timestamp(System.currentTimeMillis());
			workOrder.setLastUpdateTime(time);
			workOrder.setCloseTime(time);
			workOrderList.add(workOrder);
		}
		// 批量关闭工单
		closeBatch(workOrderList, userId);
	}



	/**
	 * TODO 添加任务超时记录
	 *
	 * @param
	 * @param nodeId
	 */
	private void addTaskTimeOutRecordInfo(WorkOrder workOrder, String nodeId) {
		String processInstanceId = workOrder.getProcessInstanceId();

		if (StringUtils.isEmpty(processInstanceId) || StringUtils.isEmpty(nodeId)) {
			log.info("流程实例或者，流程节点id为空，添加任务超时记录失败！");
			return;
		}

		String runTaskId = ActTaskServiceUtil.getActiveTaskIdByProcessInstId(processInstanceId);
		if (StringUtils.isEmpty(runTaskId)) {
			log.info("未查到" + processInstanceId + "流程实例下正在运行的任务id，添加任务超时记录失败！");
			return;
		}

		// 删除该流程实例的其他任务记录数据
		taskTimeOutRecordDao.deleteByProcessInstanceId(processInstanceId);

		// 修改工单超时状态
		updateWorkOrderTimeOut(workOrder.getId(), processInstanceId, FieldEnum.NOT_TIME_OUT.getCode());

		// 修改超时工单，是否已处理状态
		updateHandleState(workOrder.getId(), ConstantCode.Y);

		// 创建新的工单任务
		TaskTimeOutRecord taskTimeOutRecord = new TaskTimeOutRecord();
		taskTimeOutRecord.setTaskId(runTaskId);
		taskTimeOutRecord.setProcessInstanceId(processInstanceId);
		taskTimeOutRecord.setNodeId(nodeId);
		taskTimeOutRecord.setStartTime(new Date());
		taskTimeOutRecord.setIsTimeOut(ConstantCode.N);
		taskTimeOutRecord.setTenantId(workOrder.getTenantId());
		taskTimeOutRecordDao.insertSelective(taskTimeOutRecord);
	}

	/**
	 * TODO 修改超时工单是否处理状态
	 *
	 * @param
	 * @param
	 */
	private void updateHandleState(String workOrderId, String isTimeOutHandle) {
		WorkOrderLog workOrderLog = new WorkOrderLog();
		workOrderLog.setWorkOrderId(workOrderId);
		workOrderLog.setIsTimeOutHandle(isTimeOutHandle);
		workOrderLogDao.updateHandleStateByWorkOrderId(workOrderLog);
	}

	/**
	 * TODO 修改工单超时状态
	 *
	 * @param processInstanceId
	 * @param isTimeOut
	 */
	private void updateWorkOrderTimeOut(String workOrderId, String processInstanceId, String isTimeOut) {
		WorkOrderRelation workOrderRelation = new WorkOrderRelation();
		workOrderRelation.setWorkOrderId(workOrderId);
		workOrderRelation = workOrderRelationMapper.selectWorkOrderRelation(workOrderRelation);
		if (workOrderRelation != null) {
			workOrderRelation.setIsTimeOut(isTimeOut);
			workOrderRelationMapper.updateWorkOrderRelation(workOrderRelation);
		}
	}

	/**
	 * @Author: Donny_dong
	 * @Description: 根据工单id获取一条WorkOrderRelation
	 * @Param:
	 * @return:
	 * @Date: 2020/4/26
	 */
	public WorkOrderRelation getByWorkOrderId(String workOrderId) {
		WorkOrderRelation workOrderRelation = new WorkOrderRelation();
		workOrderRelation.setWorkOrderId(workOrderId);
		workOrderRelation = workOrderRelationMapper.selectWorkOrderRelation(workOrderRelation);
		return workOrderRelation;
	}

	/**
	 * TODO 创建关联工单
	 *
	 * @param currentWorkOrderId 当前创建工单id
	 * @param concatWorkOrderId  需要关联工单id
	 * @author: victor_tang
	 * @createtime: 2019/10/4 15:53
	 * @return: void
	 */
	private void createConcatWorkOrder(String currentWorkOrderId, String concatWorkOrderId) {
		if (concatWorkOrderId == null || concatWorkOrderId == "") {
			return;
		}
		WorkOrderRelation workOrderRelation = new WorkOrderRelation();
		workOrderRelation.setWorkOrderId(concatWorkOrderId);
		workOrderRelation = workOrderRelationMapper.selectWorkOrderRelation(workOrderRelation);
		if (workOrderRelation == null) {
			log.info("未找到工单id为" + concatWorkOrderId + "的信息！");
			return;
		}
		String concatWorkOrderIdStr = workOrderRelation.getConcatWorkOrderIdStr();
		// 拼接关联工单id
		if (StringUtils.isEmpty(concatWorkOrderIdStr)) {
			concatWorkOrderIdStr = currentWorkOrderId;
		} else {
			concatWorkOrderIdStr = concatWorkOrderIdStr + "," + currentWorkOrderId;
		}
		workOrderRelation.setConcatWorkOrderIdStr(concatWorkOrderIdStr);
		Integer result = workOrderRelationMapper.updateWorkOrderRelation(workOrderRelation);
		if (result == null || result == 0) {
			log.info("关联工单失败！");
		}
	}

	/**
	 * TODO 组装工单信息
	 *
	 * @param workOrder    1
	 * @param workOrderDto 2
	 * @author: victor_tang
	 * @createtime: 2019/9/25 20:37
	 * @return: com.egoo.ews.service.vo.WorkOrder
	 */
	private WorkOrder addWorkOrderInfo(WorkOrder workOrder, WorkOrderDto workOrderDto) {
		// 关联工单
		workOrderDto.setProcessInstanceId(workOrder.getProcessInstanceId());
		workOrder.setWorkOrderTypeId(workOrderDto.getWorkOrderTypeId());
		// 获取工单类型名称
		String workOrderTypeName = workOrderTypeDao.selectById(workOrderDto.getWorkOrderTypeId()).getName();
		workOrder.setWorkOrderTypeName(workOrderTypeName);
		workOrder.setHistoryHandlerId(workOrderDto.getUserId());
		workOrder.setCustomField(assembleCustomField(workOrderDto));
		workOrder.setCustomIdentify(workOrderDto.getCustomIdentify());
		workOrder.setTenantId(workOrderDto.getTenantId());
		// 获取当前用户信息
		EwsUser ewsUser = ewsUserDao.selectById(workOrderDto.getUserId());
		// 苏农定制,添加工单处理人得所属部门
		if (projectSign.equals(ProjectConstant.ProjectSign.SUNONG)) {
			workOrder.setCustomField(suNongBaseUtil.addHandleInsitution(workOrder.getCustomField(), ewsUser));
		}

		workOrder.setHistoryHandlerName(ewsUser.getName());
		workOrder.setSaveUserId(ewsUser.getId());
		workOrder.setSaveUserName(ewsUser.getName());
		Timestamp time = new Timestamp(System.currentTimeMillis());
		workOrder.setSaveTime(time);
		workOrder.setLastUserId(workOrderDto.getUserId());
		workOrder.setLastUserName(ewsUser.getName());
		workOrder.setLastUpdateTime(time);
		workOrder.setDeleteStatus(0);
		workOrder.setVoiceKeyId(workOrderDto.getVoiceKeyId());
		workOrder.setCreateUserId(ewsUser.getId());
		workOrder.setCreateUserName(ewsUser.getName());
		workOrder.setCreateTime(time);
		workOrder.setOrderCreateTime(time);
		workOrder.setId(createCodeUtil.getWorkOrderId());
//		workOrder = getAssignOrder(workOrder, workOrderDto);
		return workOrder;
	}

//	/**
//	 * @Author: Donny_dong
//	 * @Description: 获取创建时派单人
//	 * @Param:
//	 * @return:
//	 * @Date: 2020/4/20
//	 */
//	private WorkOrder getAssignOrder(WorkOrder workOrder, WorkOrderDto workOrderDto) {
//		String userId = workOrderDto.getUserId();
//		List<EwsRole> ewsRoles = ewsUserRoleDao.selectRoleByUserId(userId);
//		for (EwsRole ewsRole : ewsRoles) {
//			if (serviceRoleCode.contains(ewsRole.getCode()) &&
//					(WorkOrderState.ORDER_ALREADY_SEND == workOrder.getStatusId() ||
//							WorkOrderState.ORDER_CLOSED == workOrder.getStatusId() ||
//							WorkOrderState.ORDER_COMPLETED == workOrder.getStatusId() ||
//							WorkOrderState.ORDER_EDIT == workOrder.getStatusId() ||
//							WorkOrderState.ORDER_HANDLEING == workOrder.getStatusId() ||
//							WorkOrderState.ORDER_WAIT_CHECK == workOrder.getStatusId())) {
//				workOrder.setAssignOrder(userId);
//			}
//		}
//		return workOrder;
//	}


	/**
	 * @Author: Donny_dong
	 * @Description: 组装CustomField
	 * @Param:
	 * @return:
	 * @Date: 2020/3/31
	 */
	private JSONObject assembleCustomField(WorkOrderDto workOrderDto) {
		String processInstanceId = workOrderDto.getProcessInstanceId();
		WriteFormTemplateInputDto writeFormTemplateInputDto = workOrderDto.getWriteFormTemplateInputDto();
		Map modelValue = writeFormTemplateInputDto.getModelValue();
		JSONObject customField = workOrderDto.getCustomField();
		String classifyValue = workOrderDto.getClassifyValue();
		String taskId = writeFormTemplateInputDto.getTaskId();
		if (StringUtils.isEmpty(taskId)) {
			taskId = ActTaskServiceUtil.getActiveTaskIdByProcessInstId(processInstanceId);
		}
		TaskForm taskForm = taskFormDao.getByTaskId(taskId);
//		//服务单类型拼接（级联类拼接）
//		customField = handleCascadeData(customField, modelValue, taskForm,
//				ConstantCode.ModelValueKey.SERVE_TYPE);
		//问题描述拼接
//		customField = handleTextData(customField, modelValue, taskForm,
//				ConstantCode.ModelValueKey.PROBLEM_DESCRIPTION);

		if (!StringUtils.isEmpty(classifyValue)){
			customField.put("classifyValue",classifyValue);
		}
		customField = addModeValueToCustomField(modelValue, customField, taskForm);
		return customField;
	}

	/**
	 * @Author: Donny_dong
	 * @Description: 表单生成器内容保存到CustomField
	 * @Param:
	 * @return:
	 * @Date: 2020/6/12
	 */
	private JSONObject addModeValueToCustomField(Map modelValue, JSONObject customField,TaskForm taskForm) {

		for (Object key:modelValue.keySet()
			 ) {
			Object value = modelValue.get(key);
			if (value instanceof String){
				customField = handleCustomFieldPubData(customField, taskForm, (String) key,
						(String) value);
			}else if (value instanceof List){
				String join = StringUtils.join((List<String>) value, "/");
				customField = handleCustomFieldPubData(customField, taskForm, (String) key,
						join);
			}else if (value instanceof Long){
				String valueDate = DateHandleUtil.getFormatDateTimeByTimes((Long) value);
				customField = handleCustomFieldPubData(customField, taskForm, (String) key,
						valueDate);
			}
//			customField.put((String) key,modelValue.get(key));
		}
		return customField;
	}

	/**
	 * TODO 处理文本输入空下拉等类型自定义字段保存
	 *
	 * @param customField   1
	 * @param modelValueMap 2
	 * @param taskForm      3
	 * @param modelValueKey 4
	 * @author: victor_tang
	 * @createtime: 2020/4/29 16:02
	 * @return: com.alibaba.fastjson.JSONObject
	 */
	private JSONObject handleTextData(JSONObject customField, Map modelValueMap,
									  TaskForm taskForm, String modelValueKey) {

		String modelValue = (String) modelValueMap.get(modelValueKey);
		if (StringUtils.isEmpty(modelValue)) {
			return customField;
		}
		return handleCustomFieldPubData(customField, taskForm, modelValueKey,
				modelValue);
	}

	/**
	 * TODO 处理级联类型自定义字段保存
	 *
	 * @param customField   自定义字段
	 * @param modelValue    前端表单值
	 * @param taskForm      任务内容
	 * @param modelValueKey 类型
	 * @author: victor_tang
	 * @createtime: 2020/4/29 13:43
	 * @return: com.alibaba.fastjson.JSONObject
	 */
	private JSONObject handleCascadeData(JSONObject customField, Map modelValue,
										 TaskForm taskForm, String modelValueKey) {
		List<String> typeList = (List<String>) modelValue.get(modelValueKey);
		if (CollectionUtils.isEmpty(typeList)) {
			return customField;
		}
		//类型拼接
		String typeString = StringUtils.join(typeList, "/");
		return handleCustomFieldPubData(customField, taskForm, modelValueKey, typeString);
	}

	/**
	 * TODO 处理自定义字段拼接公共方法
	 *
	 * @param customField   1
	 * @param taskForm      2
	 * @param modelValueKey 3
	 * @param typeString    5
	 * @author: victor_tang
	 * @createtime: 2020/4/29 15:55
	 * @return: com.alibaba.fastjson.JSONObject
	 */
	private JSONObject handleCustomFieldPubData(JSONObject customField, TaskForm taskForm
			, String modelValueKey, String typeString) {
		String typeCustomField = customField.getString(modelValueKey);
		//第一次创建任务表单
		if (taskForm == null) {
			if (StringUtils.isEmpty(typeCustomField)) {
				// 之前未有该类型字段内容保存，直接替换
				customField.put(modelValueKey, typeString);
				return customField;
			}
			// 之前有该类型字段内容保存，拼接
			typeCustomField = typeCustomField + "," + typeString;
			customField.put(modelValueKey, typeCustomField);
			return customField;
		}
		// 二次编辑任务表单
		if (StringUtils.isEmpty(typeCustomField)) {
			// 之前未保存该字段
			typeCustomField = typeString;
			customField.put(modelValueKey, typeCustomField);
			return customField;

		}
		// 之前有保存该字段
		String[] split = typeCustomField.split(",");
			split[split.length - 1] = typeString;
		customField.put(modelValueKey, StringUtils.join(split, ","));
		return customField;
	}

	/**
	 * 获取工单列表
	 *
	 * @param workOrderSelectInputDto
	 * @return
	 */
	@Override
	public DbResponse select(WorkOrderSelectInputDto workOrderSelectInputDto) {
		String userId = workOrderSelectInputDto.getUserId();
		// 拼接sql条件
		String sql = joinSqlContion(workOrderSelectInputDto);
		log.info("工单列表查询sql: {}", sql);
		// 设置分页数
		PageHelper.startPage(workOrderSelectInputDto.getCurrentPage(),
				workOrderSelectInputDto.getPageSize());
		List<WorkOrder> workOrderList = workOrderDao.selectBySql(sql);
		// 获取总数
		PageInfo<WorkOrder> pageInfo = new PageInfo<>(workOrderList);
		// 处理翻译工单列表页面所需展示得字段和标识
		List<WorkOrderListOutputDto> dataList = handleWorkListData(workOrderList, userId);
		return new DbResponse(ResponseConstant.RES_SUCCESS_CODE,
				ResponseConstant.SELECT_SUCCESS_MSG, dataList, pageInfo.getTotal());
	}

	/**
	 * TODO 处理翻译工单列表页面所需展示得字段和标识
	 *
	 * @param workOrderList 1
	 * @param userId        2
	 * @author: victor_tang
	 * @createtime: 2020/4/5 21:19
	 * @return: java.util.List<com.egoo.ews.service.dto.WorkOrderListOutputDto>
	 */
	private List<WorkOrderListOutputDto> handleWorkListData(List<WorkOrder> workOrderList, String userId) {
		List<WorkOrderListOutputDto> workOrderListOutputDtoList = new ArrayList<>();
		for (int i = 0; i < workOrderList.size(); i++) {
			WorkOrderListOutputDto workOrderListOutputDto = new WorkOrderListOutputDto();
			WorkOrder workOrder = workOrderList.get(i);
			//判断工单是否被关注
			workOrder = checkWorkOrderMonitorOrCancel(workOrder, userId);
			BeanUtils.copyProperties(workOrder, workOrderListOutputDto);
			Integer statusId = workOrder.getStatusId();
			if (statusId==null) {
				throw  new RuntimeException(workOrder.getId()+"工单状态为空，请检查！");
			}
			WorkOrderStatus workOrderStatus = workOrderStatusDao.selectById(statusId,workOrder.getTenantId());
			if (workOrderStatus != null) {
				workOrderListOutputDto.setStatusName(workOrderStatus.getName());
			}
			if(workOrderList.get(i).getStatusId()==WorkOrderState.ALREAAY_CASE
					|| workOrderList.get(i).getStatusId()==WorkOrderState.ALREDAY_CLOSE){
			    workOrderListOutputDto.setIsTimeOut(ConstantCode.N);
            }

			Timestamp workOrderCreateTime = workOrder.getCreateTime();
			Timestamp workOrderLastUpdateTime = workOrder.getLastUpdateTime();
			workOrderListOutputDto.setCreateTime(sdfTime.format(workOrderCreateTime.getTime()));
			workOrderListOutputDto.setLastUpdateTime(sdfTime.format(workOrderLastUpdateTime.getTime()));
			workOrderListOutputDto.setCustomField(workOrder.getCustomField());
			// 添加工单详情跳转url
			workOrderListOutputDto.setOrderDetailUrl(orderFrontUrl+detailRoutre+"/"+workOrder.getId());
			workOrderListOutputDtoList.add(workOrderListOutputDto);
		}
		return workOrderListOutputDtoList;
	}

	/**
	 * @return void
	 * @Author Donny_Dong
	 * @Description //TODO 判断工单是否被关注
	 * @Date 15:39 2020/2/5
	 * @Param [workOrder]
	 **/
	private WorkOrder checkWorkOrderMonitorOrCancel(WorkOrder workOrder, String userId) {
		WorkOrderRelation workOrderRelation = getByWorkOrderId(workOrder.getId());
		String workOrderMonitorId = workOrderRelation.getWorkOrderMonitorId();
		if (StringUtils.isEmpty(workOrderMonitorId)) {
			workOrder.setIsMonitor(FieldEnum.IS_CANCLE.getCode());
			return workOrder;
		}

		List<String> workOrderMonitorIdList = Arrays.asList(workOrderMonitorId.split(","));
		if (workOrderMonitorIdList.contains(userId)) {
			workOrder.setIsMonitor(FieldEnum.IS_MONITOR.getCode());
		} else {
			workOrder.setIsMonitor(FieldEnum.IS_CANCLE.getCode());
		}
		return workOrder;
	}

	/**
	 * TODO 拼接SQL条件
	 * @author: victor_tang
	 * @createtime: 2020/5/15 10:40
	 * @param workOrderSelectInputDto 1
	 * @return: java.lang.String
	 */
	@Override
	public String joinSqlContion(WorkOrderSelectInputDto workOrderSelectInputDto) {
		Integer filterId = workOrderSelectInputDto.getWorkOrderFilterId();
		String userId = workOrderSelectInputDto.getUserId();
		String tenantId = workOrderSelectInputDto.getTenantId();
		String sql = null;
		WorkOrderFilterMenu workOrderFilterMenu = workOrderFilterMenuDao.selectById(filterId,tenantId);
		String filterName = workOrderFilterMenu.getName();
		userId = handleSqlInjectionUtil.filter(userId);
		tenantId = handleSqlInjectionUtil.filter(tenantId);
		// 系统默认过滤器条件
		if (SysFilter.ALL_FILTER_NAME.equals(filterName)
				|| SysFilter.CREATE_FILTER_NAME.equals(filterName)
				|| SysFilter.EDIT_FILTER_NAME.equals(filterName)
				|| SysFilter.MONITOR_FILTER_NAME.equals(filterName)
				|| SysFilter.WAIT_HANDLE_FILTER_NAME.equals(filterName)
                || SysFilter.FINISHED_FILTER_NAME.equals(filterName)
                || SysFilter.FROM_DEPT_FILTER_NAME.equals(filterName)
		) {
			// 拼接系统默认过滤器sql
			sql = dynamicSqlJoinUtil.selectByDynamicSystem(filterId, filterName, userId,tenantId);
		} else {
			// 普通过滤器条件
			sql = workOrderFilterMenuService.selectByDynamic(filterId, userId, tenantId);
		}
		//高级筛选查询SQL处理
		sql = advancedSelectCondition(workOrderSelectInputDto,sql);
//		普通搜索查询
//		sql = generalSelectCondition(workOrderSelectInputDto,sql);
		if(ProjectConstant.ProjectSign.JINCHNEG.equals(projectSign)){
			sql = jinChengBaseUtil.jinChengSelectCondition(sql, workOrderSelectInputDto);
		}

		// 添加为删除条件
		sql += " and a.delete_status = 0";

		// 添加租户筛选条件
		sql += " and (a.tenant_id = 'sys' or a.tenant_id = '" + tenantId + "')";

		// 添加工单类型筛选条件
		Long workOrderTypeId = workOrderFilterMenu.getWorkOrderTypeId();
		// 0 和 1 均为系统内置类型菜单的所属工单类型，不做筛选
		if (workOrderTypeId != null && workOrderTypeId != 0 && workOrderTypeId != 1) {
			sql += " and a.work_order_type_id = " + workOrderTypeId + "";
		}
		// 排序字段
		String field = workOrderSelectInputDto.getField();

		// 排序标识
		Integer sortTag = workOrderSelectInputDto.getSortTag();
		if (null != field && null != sortTag && !"".equals(field)) {
			// 自定义字段排序
			if ("statusName".equals(field)) {
				field = "a.status_id";
			} else if ("workOrderTypeName".equals(field)) {
				field = "a.work_order_type_name";
			} else if ("clientName".equals(field)) {
				field = "a.client_name";
			} else if ("currentHandlerName".equals(field)) {
				field = "a.current_handler_name";
			} else if ("createTime".equals(field)) {
				field = "a.create_time";
			} else if ("lastUpdateTime".equals(field)) {
				field = "a.last_update_time";
			}
			if (sortTag == 0) {
				sql += " order by " + field + " asc";
			} else {
				sql += " order by " + field + " desc";
			}
		} else {
			// 默认排序 mysql中的用法
			sql += " order by a.status_id="+WorkOrderState.ALREAAY_CASE+","
                    +" a.status_id="+WorkOrderState.ALREDAY_CLOSE +","
                    +" b.is_time_out desc, a.create_time" +" desc";
//			oracle中的用法
//			sql += " order by " +"case a.status_id when "+WorkOrderState.ALREAAY_CASE+" then "+WorkOrderState.ALREAAY_CASE+" when "+WorkOrderState.ALREDAY_CLOSE+" then "+WorkOrderState.ALREDAY_CLOSE+" END,"
//					+" b.is_time_out desc, a.create_time" +" desc";
		}
		return sql;
	}
	/**
	 * @Author: Donny_dong
	 * @Description: 普通搜索查询SQL处理
	 * @Param:
	 * @return:
	 * @Date: 2020/9/7
	 */
	private String generalSelectCondition(WorkOrderSelectInputDto workOrderSelectInputDto, String sql) {
		// 添加搜索内容
		String searchContent = workOrderSelectInputDto.getSearchContent();
		if (null != searchContent && !"".equals(searchContent)) {
			sql += " and (a.id  like '%" + searchContent + "%'"
					+ " OR  a.title like '%" + searchContent + "%'"
					+ " OR  a.client_name like '%" + searchContent + "%'"
					+ " OR  a.create_user_name like '%" + searchContent + "%'"
					+ " OR  a.phone like '%" + searchContent + "%'"
					+ " OR  a.current_handler_name like '%" + searchContent +
					"%')";
		}
		// 工单类型名称
		String workOrderTypeName = workOrderSelectInputDto.getWorkOrderTypeName();
		if (null != workOrderTypeName && !"".equals(workOrderTypeName)) {
			if (!workOrderTypeName.equals(ConstantCode.UserRoleDeptType.ALL)) {
				sql += " AND a.work_order_type_name = '" + workOrderTypeName + "'";
			}
		}
		// 工单id
		String workOrderId = workOrderSelectInputDto.getWorkOrderId();
		if (StringUtils.isNotBlank(workOrderId)) {
			sql += " AND a.id like '%" + workOrderId+"%'";
		}
		// 工单id
		String currentHandlerId = workOrderSelectInputDto.getCurrentHandlerId();
		if (StringUtils.isNotBlank(currentHandlerId)) {
			sql += " AND find_in_set('"+currentHandlerId+"',"+"a.current_handler_id)";
		}
		// 工单状态id
		Integer workOrderStatusId = workOrderSelectInputDto.getWorkOrderStatusId();
		if (workOrderStatusId != null && workOrderStatusId != 0) {
			sql += " AND a.status_id = " + workOrderStatusId;
		}
		// 工单创建时间段
		List<String> createTime = workOrderSelectInputDto.getCreateTime();
		String startTime = null;
		String endTime = null;
		if (null != createTime && createTime.size() > 0) {
			for (int i = 0; i < createTime.size(); i++) {
				if (i == 0) {
					startTime = createTime.get(i);
				} else {
					endTime = createTime.get(i);
				}
			}
			sql += " and a.create_time >= '" + startTime + "' and '" + endTime
					+ "' >= a.create_time";
		}
		// 座席工号和姓名
		String createUserName = workOrderSelectInputDto.getCreateUserName();
		if (StringUtils.isNotBlank(createUserName)) {
			sql += " AND (a.create_user_name like '%" + createUserName + "%'" + " or "
					+ "a.create_user_name in (select name from ews_user where" +
					"  user_name like '%" + createUserName
					+ "%'))";
		}
		// 处理客户定制字段sql拼接
		Map<String, String> customField = JSONObject.toJavaObject(workOrderSelectInputDto.getCustomField(), Map.class);
		if (customField != null) {
			for (String key : customField.keySet()) {
				if (StringUtils.isEmpty(customField.get(key))) {
					continue;
				}
				// 因业务类型一和业务类型二共用一个筛选条件，故特殊处理
				if (OrderTypeField.SERVE_TYPE.equals(key)) {
					sql += " AND ((a.custom_field -> '$.seviceType') like '%" + customField.get(key) + "%')";
				} else if (OrderTypeField.ORDER_TYPE.equals(key)) {
					sql += " AND ((a.custom_field -> '$.orderType') like '%" + customField.get(key) + "%')";
				} else {
					sql += " AND ((a.custom_field -> '$." + key + "')= '" + customField.get(key) + "')";
				}
			}
		}
		return sql;
	}

	/**
	 * @Author: Donny_dong
	 * @Description: 高级筛选条件处理
	 * @Param:
	 * @return:
	 * @Date: 2020/9/2
	 */
	private String advancedSelectCondition(WorkOrderSelectInputDto workOrderSelectInputDto,String sql) {
		List<List> advancedSelect = workOrderSelectInputDto.getAdvancedSelect();
		Integer workOrderFilterId = workOrderSelectInputDto.getWorkOrderFilterId();
		if (CollectionUtils.isEmpty(advancedSelect)){
			return sql;
		}
		sql = handleSqlCondition(advancedSelect,sql,workOrderFilterId);
		return sql;
	}

	/**
	 * @Author: Donny_dong
	 * @Description: 处理SQL条件
	 * @Param:
	 * @return:
	 * @Date: 2020/9/2
	 */
	private String handleSqlCondition(List<List> advancedSelect,String sql,Integer workOrderFilterMenuId) {
		JSONArray jsonArray = CommonUtil.readConfig("/headfieldconfig/sysFilterHeadField-"+projectSign+".json");
		List<TableHeadField> tableHeadFieldList = JSON.parseArray(jsonArray.toJSONString(),TableHeadField.class);
		List<String> props = tableHeadFieldList.stream().map(tableHeadField -> tableHeadField.getProp()).collect(Collectors.toList());
		TableHeadFieldDto tableHeadFieldDto = new TableHeadFieldDto();
		tableHeadFieldDto.setWorkOrderFilterMenuId(Long.valueOf(workOrderFilterMenuId));
		List<TableHeadField> tableHeadFields = headFieldMapper.selectByFilterId(tableHeadFieldDto);
		if (workOrderFilterMenuId ==ConstantCode.SysFilter.ALL_FILTER_ID
				|| workOrderFilterMenuId == ConstantCode.SysFilter.CREATE_FILTER_ID
				|| workOrderFilterMenuId == ConstantCode.SysFilter.EDIT_FILTER_ID
				|| workOrderFilterMenuId == ConstantCode.SysFilter.MONITOR_FILTER_ID
				|| workOrderFilterMenuId == ConstantCode.SysFilter.WAIT_HANDLE_FILTER_ID
				|| workOrderFilterMenuId ==ConstantCode.SysFilter.FINISHED_FILTER_ID
				|| workOrderFilterMenuId == ConstantCode.SysFilter.FROM_DEPT_FILTER_ID){
				tableHeadFields.addAll(tableHeadFieldList);
		}
		for (List list:advancedSelect) {
			String param = (String) list.get(0);
			String condition = (String) list.get(1);
			Object value = list.get(2);
			for (TableHeadField tableHeadField:tableHeadFields) {
				if (!param.equals(tableHeadField.getProp())) {
					continue;
				}
				String type = tableHeadField.getType();
				String belongToTable = getBelongToTable(workOrderFilterMenuId, tableHeadFieldList, props, param);
				String alias = CommonUtil.checkParamType(belongToTable);
				String symbol = CommonUtil.symbolTranslation(condition);
				sql = appendSql(belongToTable, symbol, alias, value, sql, param, type);
			}
		}
		return sql;
	}
	/**
	 * @Author: Donny_dong
	 * @Description: 拼接SQL
	 * @Param:
	 * @return:
	 * @Date: 2020/9/4
	 */
	private String appendSql(String belongToTable, String symbol, String alias, Object value, String sql,String param,String type) {
		alias = handleSqlInjectionUtil.filter(alias);
		param = handleSqlInjectionUtil.filter(param);
		if ( value instanceof List){
			if (CollectionUtils.isEmpty((List)value)){
				return sql;
			}
			List<String> valueList = (List<String>) value;
			if ( FormTemplateType.CASCADER.equals(type)) {
				String join = StringUtils.join(valueList, "/");
				if (BelongToTable.WORK_ORDER_CUSTOMFIELD.equals(belongToTable)) {
					sql += " AND ((a.custom_field -> '$."+param+"') "+"like"+" '%" + join + "%')";
					return sql;
				}
				sql += " and find_in_set("+join+","+alias+param+")";
				return sql;
			}
			else if (FormTemplateType.DATE_TIME_RANGE.equals(type)
					||FormTemplateType.DATE_RANGE.equals(type)){
				if (BelongToTable.WORK_ORDER_CUSTOMFIELD.equals(belongToTable)) {
					sql += "";
					return sql;
				}
				String start = valueList.get(0);
				String end = valueList.get(1);
				start = handleSqlInjectionUtil.filter(start);
				end = handleSqlInjectionUtil.filter(end);
				sql += " and "+alias+param+" "+">= '"+start+"' and "+alias+param+" "+"<= '"+end+"'";
				return sql;
			}
		}
		value = handleSqlInjectionUtil.filter(value+"");
		if (value ==null || value ==""){
			return sql;
		}
		if (BelongToTable.WORK_ORDER_CUSTOMFIELD.equals(belongToTable)){
			if (symbol.equals("like") || symbol.equals("contain")) {
				sql += " AND ((a.custom_field -> '$."+param+"') "+"like"+" '%" + value + "%')";
			}else {
				sql += " AND ((a.custom_field -> '$."+ param +"') "+symbol+" '" + value + "')";
			}
			return sql;
		}

		if (symbol.equals("like")) {
			sql += " and "+alias+param+" "+symbol+" '%"+value+"%'";
//			if (ProjectConstant.ProjectSign.JINCHNEG.equals(projectSign)){
//
//			}
		}else if (symbol.equals("contain")){
			sql += " and find_in_set('"+value+"',"+alias+param+")";
		}else {
			sql += " and "+alias+param+" "+symbol+" '"+value+"'";
		}

		return sql;
	}

	/**
	 * @Author: Donny_dong
	 * @Description: 获取对应表名
	 * @Param:
	 * @return:
	 * @Date: 2020/9/4
	 */
	private String getBelongToTable(Integer workOrderFilterMenuId, List<TableHeadField> tableHeadFieldList, List<String> props, String param) {
		String belongToTable = null;
		if (workOrderFilterMenuId ==ConstantCode.SysFilter.ALL_FILTER_ID
				|| workOrderFilterMenuId == ConstantCode.SysFilter.CREATE_FILTER_ID
				|| workOrderFilterMenuId == ConstantCode.SysFilter.EDIT_FILTER_ID
				|| workOrderFilterMenuId == ConstantCode.SysFilter.MONITOR_FILTER_ID
				|| workOrderFilterMenuId == ConstantCode.SysFilter.WAIT_HANDLE_FILTER_ID || workOrderFilterMenuId ==ConstantCode.SysFilter.FINISHED_FILTER_ID
				|| workOrderFilterMenuId == ConstantCode.SysFilter.FROM_DEPT_FILTER_ID){

			int i = props.indexOf(param);
			belongToTable = tableHeadFieldList.get(i).getBelongToTable();
		}else {
			TableHeadField tableHeadField = headFieldMapper.selectByCode(param,workOrderFilterMenuId);
			belongToTable = tableHeadField.getBelongToTable();
		}
		return belongToTable;
	}

	/**
	 * TODO 交互页面工单列表查询
	 *
	 * @param workOrderSelectInputDto 1
	 * @author: victor_tang
	 * @createtime: 2019/9/20 16:04
	 * @return: com.egoo.ews.service.utils.DBResponse
	 */
	@Override
	public DbResponse getWorkOrderList(WorkOrderSelectInputDto workOrderSelectInputDto) {
		workOrderSelectInputDto = handleParam(workOrderSelectInputDto);

		// 设置分页参数
		PageHelper.startPage(workOrderSelectInputDto.getCurrentPage(),
				workOrderSelectInputDto.getPageSize());
		List<WorkOrder> workOrderList = workOrderDao.selectWorkOrderList(workOrderSelectInputDto);
		// 获取总数
		PageInfo<WorkOrder> pageInfo = new PageInfo<>(workOrderList);
		// 翻译字段
		workOrderList = translateField(workOrderList,
				workOrderSelectInputDto.getUserId());

		return DbResponse.getDbResponse(ResponseConstant.RES_SUCCESS_CODE, ResponseConstant.SELECT_SUCCESS_MSG,
				workOrderList, pageInfo.getTotal());
	}

	/**
	 * TODO 翻译组装字段
	 *
	 * @param workOrderList 1
	 * @author: victor_tang
	 * @createtime: 2019/9/23 23:07
	 * @return: java.util.List<com.egoo.ews.service.vo.WorkOrder>
	 */
	private List<WorkOrder> translateField(List<WorkOrder> workOrderList,
										   String userId) {
		if (workOrderList == null || workOrderList.size() == 0) {
			return workOrderList;
		}

		for (WorkOrder workOrder : workOrderList) {
			// 创建时间格式化
			if (workOrder.getCreateTime() != null) {
				workOrder.setCreateTimeStr(sdfTime.format(workOrder.getCreateTime()));
			}

			// 工单状态名称
			if (workOrder.getStatusId() != null) {
				WorkOrderStatus workOrderStatusInfo = workOrderStatusDao.selectById(workOrder.getStatusId(),workOrder.getTenantId());
				if (workOrderStatusInfo != null) {
					workOrder.setStatusName(workOrderStatusInfo.getName());
				}
			}
		}

		return workOrderList;
	}

	/**
	 * TODO 处理工单分页列表查询参数
	 *
	 * @param workOrderSelectInputDto 1
	 * @author: victor_tang
	 * @createtime: 2019/9/20 22:22
	 * @return: com.egoo.ews.service.dto.WorkOrderSelectInputDto
	 */
	private WorkOrderSelectInputDto handleParam(WorkOrderSelectInputDto workOrderSelectInputDto) {

		List<String> createTimeList = workOrderSelectInputDto.getCreateTime();

		if (createTimeList != null && createTimeList.size() > 1) {
			workOrderSelectInputDto.setStartDate(createTimeList.get(0));
			workOrderSelectInputDto.setEndDate(createTimeList.get(1));
		}
		workOrderSelectInputDto = getCustomFieldSelectSql(workOrderSelectInputDto);
		return workOrderSelectInputDto;
	}

	/**
	 * @Author: Donny_dong
	 * @Description: 拼接自定义字段的SQL
	 * @Param:
	 * @return:
	 * @Date: 2020/8/26
	 */
	private WorkOrderSelectInputDto getCustomFieldSelectSql(WorkOrderSelectInputDto workOrderSelectInputDto) {
		JSONObject customField = workOrderSelectInputDto.getCustomField();
		String sql = "";
		if (!Objects.isNull(customField)){
			Map<String,String> map = JSONObject.toJavaObject(customField, Map.class);
			for (String key:map.keySet()) {
				if (Objects.isNull(customField.get(key))) {
					continue;
				}
				sql = " or ((custom_field -> '$." + key + "') like '%" + customField.get(key) + "%')";
			}
		}
		else if (!StringUtils.isEmpty(workOrderSelectInputDto.getConcatAndMergeStr())){
			String concatAndMergeStr = workOrderSelectInputDto.getConcatAndMergeStr();
			if (StringUtils.isEmpty(concatAndMergeStr)) {
				workOrderSelectInputDto.setConcatAndMergeData(null);
				return workOrderSelectInputDto;
			}
			List<String> list = Arrays.asList(concatAndMergeStr.split(","));
			workOrderSelectInputDto.setConcatAndMergeData(list);
		}
//		else if(!StringUtils.isEmpty(workOrderSelectInputDto.getMergeIdStr())){
//			String mergeIdStr = workOrderSelectInputDto.getMergeIdStr();
//			if (StringUtils.isEmpty(mergeIdStr)) {
//				workOrderSelectInputDto.setConcatAndMergeDate(null);
//				return workOrderSelectInputDto;
//			}
//			List<String> list = Arrays.asList(mergeIdStr.split(","));
//			workOrderSelectInputDto.setConcatAndMergeDate(list);
//		}
		if(StringUtils.isNotBlank(workOrderSelectInputDto.getWorkOrderId())){
			sql = sql + " or id like '%"+workOrderSelectInputDto.getWorkOrderId()+"%'";
		}
		if (StringUtils.isNotBlank(sql)) {
			sql = sql.replaceFirst("or", "and (")+")";
		}
		workOrderSelectInputDto.setSql(sql);
		return workOrderSelectInputDto;
	}


	/**
	 * TODO 获取关联工单列表
	 *
	 * @param workOrderDto 关联工单id
	 * @author: victor_tang
	 * @createtime: 2019/10/4 16:46
	 * @return: java.util.List<com.egoo.ews.service.dto.WorkOrderAttributeOutputDto>
	 */
	@Override
	public DbResponse selectConcatWorkOrderList(WorkOrderDto workOrderDto) {
		// 组装转化关联工单id
		WorkOrderRelation workOrderRelation = new WorkOrderRelation();
		workOrderRelation.setWorkOrderId(workOrderDto.getWorkOrderId());
		workOrderRelation = workOrderRelationMapper.selectWorkOrderRelation(workOrderRelation);
		String contactWorkOrderIdStr = workOrderRelation.getConcatWorkOrderIdStr();
		if (StringUtils.isEmpty(contactWorkOrderIdStr)) {
			log.info("获取的关联工单id为空");
			return new DbResponse(ResponseConstant.RES_SUCCESS_CODE, ResponseConstant.SELECT_SUCCESS_MSG);
		}

		List<String> idsStr = Arrays.asList(contactWorkOrderIdStr.split(","));
		// 查询关联工单列表
		PageHelper.startPage(workOrderDto.getPageNumber(), workOrderDto.getPageSize());
		List<WorkOrder> concatWorkOrderList = workOrderDao.selectWorkOrderListByIds(idsStr);
		PageInfo<WorkOrder> pageInfo = new PageInfo<>(concatWorkOrderList);
		return new DbResponse(ResponseConstant.RES_SUCCESS_CODE, ResponseConstant.SELECT_SUCCESS_MSG,
				concatWorkOrderList, pageInfo.getTotal());
	}

	/**
	 * TODO 取消关联工单
	 *
	 * @param currentWorkOrderId 1
	 * @param concatWorkOrderId  2
	 * @author: victor_tang
	 * @createtime: 2019/10/4 17:28
	 * @return: com.egoo.ews.service.utils.DBResponse
	 */
	@Override
	public DbResponse cancleConcatWorkOrder(String concatWorkOrderId, String currentWorkOrderId) {
		// 双向取消关联工单
		updateConcatWorkOrder(currentWorkOrderId, concatWorkOrderId);
		updateConcatWorkOrder(concatWorkOrderId, currentWorkOrderId);

		return new DbResponse(ResponseConstant.RES_SUCCESS_CODE, ResponseConstant.CANCEL_CONCAT_SUCCESS_MSG);
	}

	/**
	 * TODO 修改关联工单关系
	 *
	 * @param concatWorkOrderId  1
	 * @param currentWorkOrderId 2
	 * @author: victor_tang
	 * @createtime: 2019/10/5 9:16
	 * @return: java.lang.Integer
	 */
	private Integer updateConcatWorkOrder(String concatWorkOrderId, String currentWorkOrderId) {
		WorkOrderRelation workOrderRelation = new WorkOrderRelation();
		workOrderRelation.setWorkOrderId(currentWorkOrderId);
		workOrderRelation = workOrderRelationMapper.selectWorkOrderRelation(workOrderRelation);
		String concatWorkOrderIdStr = workOrderRelation.getConcatWorkOrderIdStr();
		StringBuffer sb = new StringBuffer();
		if (StringUtils.isNotBlank(concatWorkOrderIdStr)) {
			String[] ids = concatWorkOrderIdStr.split(",");
			// 删除当前工单id
			for (String id : ids) {
				if (!concatWorkOrderId.equals(id)) {
					sb.append(id).append(",");
				}
			}
		}

		// 更新关联工单id
		if (sb.length() > 0) {
			sb.deleteCharAt(sb.length() - 1);
			workOrderRelation.setConcatWorkOrderIdStr(sb.toString());
		} else {
			workOrderRelation.setConcatWorkOrderIdStr("");
		}
		return workOrderRelationMapper.updateWorkOrderRelation(workOrderRelation);
	}

	/**
	 * TODO 获取工单处理信息
	 * @author: victor_tang
	 * @createtime: 2020/5/18 13:55
	 * @param id 1
	 * @param userId 2
	 * @return: com.egoo.ews.service.pojo.dto.ProcessMessageOutputDto
	 */
	@Override
	public ProcessMessageOutputDto getProcessMessage(String id, String userId) {
		ProcessMessageOutputDto dto = new ProcessMessageOutputDto();
		WorkOrder workOrder = workOrderDao.selectById(id);
		// 处理工单回显详情信息
		dto = handleWorkOrderViewInfo(workOrder, userId, dto);

		// 设置工单任务表单信息
		dto = setWorkOrderTaskFormInfo(workOrder, dto);

		return dto;
	}
	/**
	 * TODO 设置工单任务表单信息
	 * @author: victor_tang
	 * @createtime: 2020/5/18 15:17
	 * @param workOrder 1
	 * @param dto 2
	 * @return: com.egoo.ews.service.pojo.dto.ProcessMessageOutputDto
	 */
	private ProcessMessageOutputDto setWorkOrderTaskFormInfo(WorkOrder workOrder, ProcessMessageOutputDto dto) {
		String processInstanceId = workOrder.getProcessInstanceId();
		Long currentNodeId = workOrder.getCurrentWorkOrderNodeId();
		WorkOrderTypeNodeVo workOrderTypeNodeVo = workOrderTypeNodeDao.getNodeByWorkOrderNodeId(currentNodeId);

		Integer nodeTag = workOrderTypeNodeVo.getTag();
		// 获取节点处理信息-------------
		List<WorkOrderNodeDto> workOrderNodeDtoList =
				workOrderDao.getWorkOrderNodeDtoList(workOrder.getId());
		Integer taskFormSize = workOrderNodeDtoList.size();

		// 获取创建节点模板信息
		WorkOrderNodeDto startTaskNodeDto = workOrderNodeDtoList.get(0);

		// 工单流转中的最近一次节点处理信息------------
		WorkOrderNodeDto workOrderTaskNodeDto = workOrderNodeDtoList.get(taskFormSize - 1);

		// 工单流转中的最近一次处理节点
		WorkOrderTypeNodeVo taskNodeVo = workOrderTypeNodeDao
				.getNodeByWorkOrderNodeId(workOrderTaskNodeDto.getNodeId());
		// 已处理的节点集合
		List<WorkOrderNodeDto> processedWorkOrderNodeDtoList = new ArrayList<>();
		// 创建当前节点
		WorkOrderCreateNodeDto currentNodeDto = new WorkOrderCreateNodeDto();
		// 获取节点模板content内容
		JSONObject content = getformTemplateContent(workOrderTypeNodeVo);
		currentNodeDto.setFormTemplate(content);
		currentNodeDto.setTaskId("123TaskId");
		if (null != nodeTag) {
			dto.setAlterFormTag(0);
			currentNodeDto.setNodeId(currentNodeId);
			JSONArray sequenceFlows = workOrderTypeNodeVo.getContent().getJSONArray("sequenceFlows");
			currentNodeDto.setSequenceFlows(sequenceFlows);
			if (null != taskNodeVo.getTag()) {
				startTaskNodeDto = new WorkOrderNodeDto();
				WorkOrderNodeDto workOrderNodeDto = workOrderNodeDtoList.get(taskFormSize - 1);
				currentNodeDto.setNodeName(workOrderNodeDto.getNodeName());
				currentNodeDto.setTaskId(workOrderNodeDto.getTaskId());
				currentNodeDto.setFormTemplate(workOrderNodeDto.getNodeContent());
				// 该工单的当前节点有处理信息
				dto.setAlterFormTag(1);
				workOrderNodeDtoList.remove(taskFormSize - 1);
				processedWorkOrderNodeDtoList = workOrderNodeDtoList;
			} else {
				currentNodeDto.setNodeName(workOrderTypeNodeVo.getName());
				processedWorkOrderNodeDtoList = workOrderNodeDtoList;
			}
		} else {
			currentNodeDto.setNodeId(currentNodeId);
			currentNodeDto.setNodeName(workOrderTypeNodeVo.getName());
			JSONArray sequenceFlows = workOrderTypeNodeVo.getContent().getJSONArray("sequenceFlows");
			currentNodeDto.setSequenceFlows(sequenceFlows);
			processedWorkOrderNodeDtoList = workOrderNodeDtoList;
			String revisability = workOrderTypeNodeVo.getContent().getString("modifyoriginalform");
			if ("1".equals(revisability)) {
				dto.setAlterFormTag(1);
			} else {
				dto.setAlterFormTag(0);
			}
		}

		if (processedWorkOrderNodeDtoList.size() == 0) {
			if (ConstantCode.WorkOrderState.ALREDAY_CLOSE==workOrder.getStatusId()
					||ConstantCode.WorkOrderState.ALREAAY_CASE==workOrder.getStatusId()
			) {
				startTaskNodeDto.setTaskId(currentNodeDto.getTaskId());
				startTaskNodeDto.setNodeName(currentNodeDto.getNodeName());
				startTaskNodeDto.setNodeId(currentNodeDto.getNodeId());
				startTaskNodeDto.setNodeContent(currentNodeDto.getFormTemplate());
				startTaskNodeDto.setHandlerId(workOrder.getCloseUserId());
				startTaskNodeDto.setHandlerName(workOrder.getCloseUserName());
				startTaskNodeDto.setSubmitTime(sdfTime.format(workOrder.getCloseTime()));
			}
		}

		dto.setCurrentNodeDto(currentNodeDto);

		dto.setStartNodeDto(startTaskNodeDto);
		if (processedWorkOrderNodeDtoList.size() > 0) {
			processedWorkOrderNodeDtoList.remove(0);
		}
		if (!CollectionUtils.isEmpty(processedWorkOrderNodeDtoList)&& !(workOrder.getStatusId() ==WorkOrderState.ALREAAY_CASE || workOrder.getStatusId() ==WorkOrderState.ALREDAY_CLOSE)) {
			WorkOrderNodeDto workOrderNodeDto = processedWorkOrderNodeDtoList.get(processedWorkOrderNodeDtoList.size() - 1);
			if(currentNodeDto.getNodeId().equals(workOrderNodeDto.getNodeId())){
				currentNodeDto.setFormTemplate(workOrderNodeDto.getNodeContent());
				processedWorkOrderNodeDtoList.remove(processedWorkOrderNodeDtoList.size()-1);
			}
		}
		dto.setProcessedWorkOrderNodeDtoList(processedWorkOrderNodeDtoList);
		// 处理撤回表单信息
			dto = resetCurrentNodeAndHistoryNode(currentNodeDto,
					processedWorkOrderNodeDtoList, processInstanceId, dto);

		return dto;
	}

	/**
	 * @Author: Donny_dong
	 * @Description: 获取模板
	 * @Param:
	 * @return:
	 * @Date: 2020/8/5
	 */
	private JSONObject getformTemplateContent(WorkOrderTypeNodeVo workOrderTypeNodeVo) {
		Integer tag = workOrderTypeNodeVo.getTag();
		if (tag==null||1!=tag) {
			// 非初始节点
			return 	workOrderTypeNodeVo.getFormTempalteContent();
		}
		String formKeySign = workOrderTypeNodeVo.getFormKeySign();
		if (WorkOrderNodeInfo.FORM_KEY_SIGN_ONE.equals(formKeySign)) {
			// 初始节点配置单模板
			return workOrderTypeNodeVo.getFormTempalteContent();
		} else if (WorkOrderNodeInfo.FORM_KEY_SIGN_MORE.equals(formKeySign)) {
			// 初始节点配置多模板
			return null;
		}
		log.error("节点模板获取为空！");
		return null;
	}

	/**
	 * TODO 处理工单详情字段
	 *
	 * @param workOrder 1
	 * @param userId    2
	 * @param dto       3
	 * @author: victor_tang
	 * @createtime: 2020/3/30 16:05
	 * @return: com.egoo.ews.service.dto.ProcessMessageOutputDto
	 */
	private ProcessMessageOutputDto handleWorkOrderViewInfo(WorkOrder workOrder, String userId,
														ProcessMessageOutputDto dto) {
		BeanUtils.copyProperties(workOrder, dto);
		dto.setCreateTime(sdfTime.format(workOrder.getCreateTime()));
		// 设置工单查询后状态
		dto = setAfterViewstatus(workOrder,dto);
		// 设置流转按钮显示标识（0不能处理 1是正常 2工单已关闭）
		dto = setFlowButtonTag(userId,workOrder,dto);
		// 设置工单是否可撤回标识
		dto.setIswithdraw(checkWorkOrderWithdraw(workOrder, userId));
		//此工单是否已被关注（Y已关注  N未关注）
		dto.setIsMonitor(checkWorkOrderMonitorOrCancel(workOrder, userId).getIsMonitor());
		// 设置工单退回按钮是否显示标识
		dto.setIsViewBackToLastStep(getIsViewBackToLastStep(workOrder));
		// 设置签到地址
		TaskSignInVo vo =
				taskSignInService.getTaskSignInByProcessInstanceId(workOrder.getProcessInstanceId(), workOrder.getTenantId());
		if (vo != null) {
			dto.setSignInAddress(vo.getSignInAddress());
		}
		// 设置领取按钮是否显示
		Long currentNodeId = workOrder.getCurrentWorkOrderNodeId();
		WorkOrderTypeNodeVo workOrderTypeNodeVo = workOrderTypeNodeDao.getNodeByWorkOrderNodeId(currentNodeId);
		dto = isRecieveShow(workOrderTypeNodeVo.getDistributeWay(), userId, dto, workOrder);
		//设置配置模板数据
		dto.setClassifyValue(getClassifyValue(workOrder));
		//设置子工单展示条件
		dto  = setIsOrNotShow(dto);
		//设置工单关注人展示
		dto  = setMonitorShow(dto);
		//设置抄送人展示
		dto  = setSenderShow(dto);
		//设置多模板标识字段
		dto  = setFormSignKey(dto);
		//设置驳回标识
		dto = setRejectedSign(userId,workOrder,dto);
		return dto;
	}

	/**
	 * @Author: Donny_dong
	 * @Description: 设置驳回按钮标识
	 * @Param:
	 * @return:
	 * @Date: 2020/8/14
	 */
	private ProcessMessageOutputDto setRejectedSign(String userId,WorkOrder workOrder,ProcessMessageOutputDto dto) {
		List<TaskForm> taskForms = taskFormDao.selectByProcessInstanceId(workOrder.getProcessInstanceId());
		Integer statusId = workOrder.getStatusId();
		if (CollectionUtils.isEmpty(taskForms) || statusId== WorkOrderState.ALREAAY_CASE || statusId ==WorkOrderState.ALREDAY_CLOSE){
			dto.setRejectedSign(ConstantCode.N);
			return dto;
		}
		TaskForm taskForm = taskForms.get(0);
		String currentTaskId =
				ActTaskServiceUtil.getActiveTaskIdByProcessInstId(workOrder.getProcessInstanceId());
		if (taskForm.getTaskId().equals(currentTaskId)){
			dto.setRejectedSign(ConstantCode.N);
			return dto;
		}
		String currentHandlerId = workOrder.getCurrentHandlerId();
		if (StringUtils.isEmpty(currentHandlerId)){
			dto.setRejectedSign(ConstantCode.N);
			return dto;
		}
		List<String> ids = Arrays.asList(currentHandlerId.split(","));
		if (taskForms.size()>=1){
			dto.setRejectedSign(ConstantCode.Y);
			return dto;
		}
		return dto;
	}

	/**
	 * @Author: Donny_dong
	 * @Description: 设置多模板字段标识
	 * @Param:
	 * @return:
	 * @Date: 2020/7/30
	 */
	private ProcessMessageOutputDto setFormSignKey(ProcessMessageOutputDto dto) {
		String classifyValue = dto.getClassifyValue();
		if (StringUtils.isEmpty(classifyValue)){
			dto.setFormKeySign(WorkOrderNodeInfo.FORM_KEY_SIGN_ONE);
			return dto;
		}
		dto.setFormKeySign(WorkOrderNodeInfo.FORM_KEY_SIGN_MORE);
		return dto;
	}

	/**
	 * @Author: Donny_dong
	 * @Description: 设置抄送人展示
	 * @Param:
	 * @return:
	 * @Date: 2020/7/24
	 */
	private ProcessMessageOutputDto setSenderShow(ProcessMessageOutputDto dto) {
		String status = getSysDictStatus(SysDictCode.SENDER);
		if (ConstantCode.STATUS_CLOSED.equals(status)) {
			dto.setIsSenderShow(ConstantCode.N);
			return dto;
		}
		dto.setIsSenderShow(ConstantCode.Y);
		String workOrderId = dto.getId();
		String tenantId = dto.getTenantId();
		WorkOrderRelation workOrderRelation = new WorkOrderRelation();
		workOrderRelation.setWorkOrderId(workOrderId);
		workOrderRelation = workOrderRelationMapper.selectWorkOrderRelation(workOrderRelation);
		String senderId = workOrderRelation.getSender();
		String senderName = getUserInfo(senderId, tenantId);
		dto.setWorkOrderSender(senderName);
		return dto;
	}

	/**
	 * @Author: Donny_dong
	 * @Description: 设置工单关注人展示
	 * @Param:
	 * @return:
	 * @Date: 2020/7/24
	 */
	private ProcessMessageOutputDto setMonitorShow(ProcessMessageOutputDto dto) {
		String status = getSysDictStatus(SysDictCode.WORK_ORDER_MONITOR_ID);
		if (ConstantCode.STATUS_CLOSED.equals(status)) {
			dto.setIsMonitorShow(ConstantCode.N);
			return dto;
		}
		dto.setIsMonitorShow(ConstantCode.Y);
		String workOrderId = dto.getId();
		String tenantId = dto.getTenantId();
		WorkOrderRelation workOrderRelation = new WorkOrderRelation();
		workOrderRelation.setWorkOrderId(workOrderId);
		workOrderRelation = workOrderRelationMapper.selectWorkOrderRelation(workOrderRelation);
		String workOrderMonitorId = workOrderRelation.getWorkOrderMonitorId();
		String monitorName = getUserInfo(workOrderMonitorId, tenantId);
		dto.setWorkOrderMonitor(monitorName);
		return dto;
	}

	/**
	 * @Author: Donny_dong
	 * @Description: 获取对应用户信息
	 * @Param:
	 * @return:
	 * @Date: 2020/7/24
	 */
	private String getUserInfo(String userIdStr,String tenantId) {
		if (StringUtils.isEmpty(userIdStr)){
			return null;
		}
		List<String> userIds = Arrays.asList(userIdStr.split(","));
		HashMap<String, Object> hashMap = new HashMap<>();
		hashMap.put("userIds",userIds);
		hashMap.put("tenantId",tenantId);
		List<EwsUser> ewsUsers = ewsUserDao.selectAllUserList(hashMap);
		String userNameStr = ewsUsers.stream().map(ewsUser -> ewsUser.getName()).collect(Collectors.joining(","));
		return userNameStr;
	}

	/**
	 * @Author: Donny_dong
	 * @Description: 设置子工单展示条件
	 * @Param:
	 * @return:
	 * @Date: 2020/5/26
	 */
	private ProcessMessageOutputDto setIsOrNotShow(ProcessMessageOutputDto dto) {
		String status = getSysDictStatus(SysDictCode.SUB_ORDER_VIEW);
		if (ConstantCode.STATUS_CLOSED.equals(status)) {
			dto.setIsShow(ConstantCode.N);
		}else {
			dto.setIsShow(ConstantCode.Y);
		}
		return dto;
	}

	/**
	 * @Author: Donny_dong
	 * @Description: ClassifyValue
	 * @Param:
	 * @return:
	 * @Date: 2020/5/25
	 */
	private String getClassifyValue(WorkOrder workOrder) {
		JSONObject customField = workOrder.getCustomField();
		String classifyValue = customField.getString("classifyValue");
		return classifyValue;
	}

	/**
	 * TODO 设置流转按钮标识
	 * @author: victor_tang
	 * @createtime: 2020/5/18 14:27
	 * @param workOrder 1
	 * @param dto 2
	 * @return: com.egoo.ews.service.pojo.dto.ProcessMessageOutputDto
	 */
	private ProcessMessageOutputDto setFlowButtonTag(String userId,
													 WorkOrder workOrder,
													 ProcessMessageOutputDto dto) {
		// 如果工单状态为关闭或者完成，则不能催单，转派，处理。
		if (dto.getStatusId() == WorkOrderState.ALREDAY_CLOSE
				|| dto.getStatusId() == WorkOrderState.ALREAAY_CASE
			) {
			dto.setContrOptionTag(FlowButtonTag.NO_HANDLE);
			return dto;
		}
		String currentHandlerId = workOrder.getCurrentHandlerId();
		if (StringUtils.isEmpty(currentHandlerId)){
			dto.setContrOptionTag(FlowButtonTag.NO_HANDLE);
			return dto;
		}
		List<String> uesrIdList = Arrays.asList(currentHandlerId.split(","));
		if (uesrIdList.contains(userId)) {
			dto.setContrOptionTag(FlowButtonTag.HANDLE);
			return dto;
		}else{
			dto.setContrOptionTag(FlowButtonTag.URGE);
			return dto;
		}
	}

	/**
	 * TODO 设置工单查看后状态
	 * @author: victor_tang
	 * @createtime: 2020/5/18 14:13
	 * @param dto 1
	 * @return: com.egoo.ews.service.pojo.dto.ProcessMessageOutputDto
	 */
	private ProcessMessageOutputDto setAfterViewstatus(WorkOrder workOrder,
													   ProcessMessageOutputDto dto) {
		WorkOrderTypeNodeVo workOrderTypeNodeVo = workOrderTypeNodeDao
				.getNodeByWorkOrderNodeId(workOrder.getCurrentWorkOrderNodeId());
		// 1.节点信息为空，查看后工单状态不变
		if (workOrderTypeNodeVo==null) {
			WorkOrderStatus workOrderStatus = workOrderStatusDao.selectById(workOrder.getStatusId(),workOrder.getTenantId());
			dto.setStatusName(workOrderStatus.getName());
			return dto;
		}
		// 2.节点配置的查看后工单状态不变，则工单状态不改变
		JSONObject currentWorkOrderNodeContent = workOrderTypeNodeVo.getContent();
		Integer afterviewstatus = currentWorkOrderNodeContent.getInteger(
				"afterviewstatus");

////		外部节点不配置查看后状态
//		if(null == afterviewstatus && workOrderTypeNodeVo.getTag()!=1){
//			return dto;
//		}
//		if (WorkOrderState.NO_CHANGE==afterviewstatus) {
//			WorkOrderStatus workOrderStatus = workOrderStatusDao.selectById(workOrder.getStatusId());
//			dto.setStatusName(workOrderStatus.getName());
//			return dto;
//		}

		if(afterviewstatus!=null&& afterviewstatus != WorkOrderState.NO_CHANGE){
			// 3.节点配置的查看后状态需要变化，根据节点配置设置
			WorkOrderStatus workOrderStatus = workOrderStatusDao.selectById(afterviewstatus,workOrder.getTenantId());
			dto.setStatusId(workOrderStatus.getId());
			dto.setStatusName(workOrderStatus.getName());
			return dto;
		}
		WorkOrderStatus workOrderStatus = workOrderStatusDao.selectById(workOrder.getStatusId(),workOrder.getTenantId());
		dto.setStatusName(workOrderStatus.getName());
		return dto;


	}

	/**
	 * @Author: Donny_dong
	 * @Description: 撤回的工单处理时，节点表单设置
	 * @Param:
	 * @return:
	 * @Date: 2020/2/14
	 */
	private ProcessMessageOutputDto resetCurrentNodeAndHistoryNode(WorkOrderCreateNodeDto currentNodeDto, List<WorkOrderNodeDto> processedWorkOrderNodeDtoList, String processInstanceId, ProcessMessageOutputDto processMessageOutputDto) {
		Integer statusId = workOrderDao.selectByProcessInstanceId(processInstanceId).getStatusId();
		if (WorkOrderState.ALREDAY_CLOSE == statusId
				|| WorkOrderState.ALREAAY_CASE == statusId
			 ) {
			return processMessageOutputDto;
		}
		WorkOrderNodeDto workOrderNodeDto = null;
		if (processedWorkOrderNodeDtoList.size() > 0) {
			workOrderNodeDto = processedWorkOrderNodeDtoList.get(processedWorkOrderNodeDtoList.size() - 1);
			String taskId = workOrderNodeDto.getTaskId();
			String withdraw = taskFormDao.getByTaskId(taskId).getNodeInfo().getString("withdraw");
//			String taskId = currentNodeDto.getTaskId();
			String currentTaskId =
					ActTaskServiceUtil.getActiveTaskIdByProcessInstId(processInstanceId);
			if (taskId.equals(currentTaskId)&&"Y".equals(withdraw)) {
				currentNodeDto.setFormTemplate(workOrderNodeDto.getNodeContent());
				List<WorkOrderNodeDto> collect = processedWorkOrderNodeDtoList.stream().filter(workOrderNode -> !currentTaskId.equals(workOrderNode.getTaskId())).collect(Collectors.toList());
				processMessageOutputDto.setCurrentNodeDto(currentNodeDto);
				processMessageOutputDto.setProcessedWorkOrderNodeDtoList(collect);
				return processMessageOutputDto;
			} else {
				return processMessageOutputDto;
			}
		} else {
			return processMessageOutputDto;
		}
	}


	/**
	 * @Author: Donny_dong
	 * @Description: 判断工单是否能被撤回
	 * @Param:
	 * @return:
	 * @Date: 2020/2/11
	 */
	private String checkWorkOrderWithdraw(WorkOrder workOrder, String userId) {
		String historyHandlerId = workOrder.getHistoryHandlerId();
		List<String> historyHandlerIdList = Arrays.asList(historyHandlerId.split(","));
		String status = getSysDictStatus(SysDictCode.ORDER_WITHDRAW);
		if (WorkOrderState.ALREDAY_CLOSE == workOrder.getStatusId()
				|| WorkOrderState.ALREAAY_CASE == workOrder.getStatusId()
				|| ConstantCode.STATUS_CLOSED.equals(status)
		) {
			return ConstantCode.N;
		}
//		TaskFormDto taskFormDto = new TaskFormDto();
//		taskFormDto.setProcessInstanceId(workOrder.getProcessInstanceId());
//		taskFormDto.setNodeId(workOrder.getCurrentWorkOrderNodeId());
//		TaskForm taskForm = taskFormDao.selectLastTaskformInfo(taskFormDto);
		if (historyHandlerIdList.size() > 0 && userId.equals(historyHandlerIdList.get(historyHandlerIdList.size() - 1))
				 && ConstantCode.STATUS_NOMAL.equals(status)) {
			return ConstantCode.Y;
		}
		return ConstantCode.N;
	}

	/**
	 * @Author: Donny_dong
	 * @Description: 获取对应字典的启用状态
	 * @Param:
	 * @return:
	 * @Date: 2020/5/25
	 */
	public String getSysDictStatus(String dictCode) {
		SysDict sysDict = new SysDict();
		sysDict.setDictCode(dictCode);
		SysDictVo sysDictVo = sysDictDao.selectOneByAny(sysDict);
		String status = null;
		if (Objects.nonNull(sysDictVo)) {
			status = sysDictVo.getStatus();
		}
		if (StringUtils.isEmpty(status)){
			status = ConstantCode.STATUS_CLOSED;
		}
		return status;
	}

	/**
	 * @return void
	 * @Author Donny_Dong
	 * @Description //TODO 工单领取展示
	 * @Date 13:26 2020/1/17
	 * @Param [distributeWay]
	 **/
	private ProcessMessageOutputDto isRecieveShow(String distributeWay, String userId, ProcessMessageOutputDto processMessageOutputDto, WorkOrder workOrder) {
		//当前工单类型节点配置为领取方式，且当前工单处理人包含当前登录用户，且当前工单未被领取，
		// 且当前工单状态不是关闭中或者已完成状态，工单可以领取
		WorkOrderRelation workOrderRelation = getByWorkOrderId(workOrder.getId());
		if (WorkOrderDistributionWay.RECIEVE_WAY.equals(distributeWay)) {
			String currentHandlerId = workOrder.getCurrentHandlerId();
			if(StringUtils.isEmpty(currentHandlerId)){
				return processMessageOutputDto;
			}
			List<String> currentHandlerIdList = Arrays.asList(currentHandlerId.split(","));
			if (currentHandlerIdList.contains(userId)
					&& !FieldEnum.IS_RECIEVE.getCode().equals(workOrderRelation.getIsRecieve())
					&& WorkOrderState.ALREDAY_CLOSE != workOrder.getStatusId()
					&& WorkOrderState.ALREAAY_CASE != workOrder.getStatusId()
			) {
				processMessageOutputDto.setDistributionWay(distributeWay);
			}
		}
		return processMessageOutputDto;
	}

	/**
	 * TODO 更新工单信息
	 * @author: victor_tang
	 * @createtime: 2020/5/25 13:11
	 * @param workOrder 1
	 * @param workOrderDto 2
	 * @param ewsUser 3
	 * @return: com.egoo.ews.service.pojo.entity.WorkOrder
	 */
	private WorkOrder addWorkOrderBaseInfo(WorkOrder workOrder,
										  WorkOrderDto workOrderDto,
										  EwsUser ewsUser) {
		// 更新工单信息
		workOrderDto.setCurrentWorkOrderNodeId(workOrder.getCurrentWorkOrderNodeId());
		workOrderDto.setProcessInstanceId(workOrder.getProcessInstanceId());
		workOrder.setCustomField(assembleCustomField(workOrderDto));
		// 苏农定制,添加工单处理人得所属部门
		if (projectSign.equals(ProjectConstant.ProjectSign.SUNONG)) {
			workOrder.setCustomField(suNongBaseUtil.addHandleInsitution(workOrder.getCustomField(), ewsUser));
		}
		workOrder.setHistoryHandlerId(workOrder.getHistoryHandlerId() + "," + ewsUser.getId());
		workOrder.setHistoryHandlerName(workOrder.getHistoryHandlerName() +
				"," + ewsUser.getName());
		workOrder.setLastUserId(ewsUser.getId());
		workOrder.setLastUserName(ewsUser.getName());
		workOrder.setLastUpdateTime(new Timestamp(System.currentTimeMillis()));
		return workOrder;
	}


	/**
	 * TODO 处理工单
	 * @author: victor_tang
	 * @createtime: 2020/5/25 11:40
	 * @param workOrderDto 1
	 * @return: com.egoo.ews.service.utils.common.DbResponse
	 */
	@Override
	public DbResponse processWorkOrder(WorkOrderDto workOrderDto) {
		// 更新工单原始表单信息
		String workOrderId = workOrderDto.getWorkOrderId();
		JSONObject opration = workOrderDto.getOpration();
		Integer status = opration.getInteger("status");
		// 获取当前用户信息
		EwsUser ewsUser = ewsUserDao.selectById(workOrderDto.getUserId());
		workOrderDto.setUserName(ewsUser.getName());
		WorkOrder workOrder = workOrderDao.selectById(workOrderId);
		Integer currentStatusId = workOrder.getStatusId();

		// 设置工单关系表信息
		WorkOrderRelation workOrderRelation = new WorkOrderRelation();

		workOrderRelation.setWorkOrderId(workOrderId);
		workOrderRelation = workOrderRelationMapper.selectWorkOrderRelation(workOrderRelation);
		if (WorkOrderState.ALREAAY_CASE != status && WorkOrderState.ALREDAY_CLOSE != status ) {
			workOrderRelation.setIsTimeOut(ConstantCode.N);
		}
		//根据操作类型设置工单状态
		workOrder = setWorkOrderStateByOptionType(workOrder,workOrderDto,ewsUser);

		// 更新工单基础信息
		workOrder = addWorkOrderBaseInfo(workOrder, workOrderDto,ewsUser);

		// 处理表单任务信息
		handleTaskFormInfo(workOrder,workOrderDto,ewsUser,currentStatusId);

		// 更新工单字段信息
		workOrder = setWorkOrderCustomField(workOrderDto,workOrder);

		// 根据操作类型处理工单信息
		workOrder = handleWorkOrderInfoByOprationType(workOrder,workOrderDto,
				ewsUser,workOrderRelation);



		if (FieldEnum.IS_RECIEVE.getCode().equals(workOrderRelation.getIsRecieve())) {
			workOrderRelation.setIsRecieve(null);
		}
		// 修改工单信息
		workOrderDao.updateWorkOrder(workOrder);
		workOrderRelationMapper.updateWorkOrderRelation(workOrderRelation);

		// 记录处理日志
		recordHandleLog(workOrder, ewsUser.getId(), workOrderDto.getOpration(),workOrderDto.getWriteFormTemplateInputDto());

		// 给redis发布消息,为触发器执行准备
		if (workOrder.getIsPubRedisTopic()) {
			mqCommonUtil.pushToMsgTriggerQueue(workOrder.getId());
			mqCommonUtil.pushToMsgGeneralQueue(MsgNotifyType.FLOW_NOTIFY,workOrder.getId());
		}
		return new DbResponse(ResponseConstant.RES_SUCCESS_CODE, "处理成功！");
	}
	/**
	 * TODO 处理表单任务信息
	 * @author: victor_tang
	 * @createtime: 2020/5/25 13:08
	 * @param workOrder 1
	 * @param workOrderDto 2
	 * @param ewsUser 3
	 * @param currentStatusId 4
	 * @return: void
	 */
	private void handleTaskFormInfo(WorkOrder workOrder, WorkOrderDto workOrderDto, EwsUser ewsUser, Integer currentStatusId) {

		// tag为1,修改原始表单
		if (workOrderDto.getTag() == 1) {
			updateStartTaskForm(workOrderDto);
		}
		// 填写当前节点表单
		WriteFormTemplateInputDto writeFormTemplateInputDto = workOrderDto.getWriteFormTemplateInputDto();
		String currentTaskId = writeFormTemplateInputDto.getTaskId();
		if (currentTaskId != null && !"123TaskId".equals(currentTaskId)) {
			updateCurrentTaskForm(workOrderDto);
		} else {
			// 获取任务id
			String taskId =
					ActTaskServiceUtil.getActiveTaskIdByProcessInstId(workOrder.getProcessInstanceId());
			// 创建表单
			createOrUpdateFormTemplate(ewsUser, workOrder.getProcessInstanceId(), taskId,
					workOrderDto, currentStatusId);
		}
	}

	/**
	 * TODO 根据操作类型处理工单信息
	 * @author: victor_tang
	 * @createtime: 2020/5/25 11:55
	 * @param workOrder 1
	 * @param workOrderDto 2
	 * @param ewsUser 3
	 * @param workOrderRelation 4
	 * @return: com.egoo.ews.service.pojo.entity.WorkOrder
	 */
	private WorkOrder handleWorkOrderInfoByOprationType(WorkOrder workOrder,WorkOrderDto workOrderDto,
														EwsUser ewsUser,
														WorkOrderRelation workOrderRelation) {
		JSONObject optation = workOrderDto.getOpration();
		String oprationType = optation.getString("type");
		workOrder.setIsPubRedisTopic(true);
		// 保存
		if (WorkOrderProcessButton.SAVE.equals(oprationType)) {
			workOrder.setCurrentHandlerId(ewsUser.getId());
			workOrder.setCurrentHandlerName(ewsUser.getName());
			workOrder.setIsPubRedisTopic(false);
		}
		// 跳转
		else if (WorkOrderProcessButton.JUMP.equals(oprationType)) {
			Long targetRefNodeId = optation.getLong("targetRef");
			WorkOrderTypeNodeVo workOrderTypeNodeVo = workOrderTypeNodeDao.getNodeByWorkOrderNodeId(targetRefNodeId);

			workOrder.setCurrentWorkOrderNodeId(targetRefNodeId);
			workOrder.setCurrentWorkOrderNodeName(workOrderTypeNodeVo.getName());
			// activiti的任意跳转
			ActCommonUtils.arbitraryJump(workOrderTypeNodeVo.getName() + targetRefNodeId, workOrder.getProcessInstanceId());
			// 非投管节点
			workOrder = setTiaoZhuanWorkOrderHandlePersonInfo(workOrder, workOrderTypeNodeVo);
			// 记录正在运行任务信息，为节点和工单超时提供计算原始数据
			addTaskTimeOutRecordInfo(workOrder, targetRefNodeId.toString());
		}
		// 转派
		else if (WorkOrderProcessButton.DISTRIBUTE.equals(oprationType)) {
			Redeploy redeploy = workOrderDto.getRedeploy();
			Long targetNodeId = redeploy.getTargetNodeId();
			String targetNodeName = workOrderTypeNodeDao.getNodeByWorkOrderNodeId(targetNodeId).getName();
			workOrder.setCurrentWorkOrderNodeId(targetNodeId);
			workOrder.setCurrentWorkOrderNodeName(targetNodeName);
			workOrderRelation.setRedeployCount(workOrderRelation.getRedeployCount() + 1);
			// activiti的任意跳转
			ActCommonUtils.arbitraryJump(targetNodeName + targetNodeId,
					workOrder.getProcessInstanceId());
			// 转派操作设置处理人
			workOrder = setZhuanPaiWorkOrderHandlePersonInfo(workOrder, redeploy);
			// 记录正在运行任务信息，为节点和工单超时提供计算原始数据
			addTaskTimeOutRecordInfo(workOrder, targetNodeId.toString());
		}
		//转出
		else if (WorkOrderProcessButton.FLOW_OUT.equals(oprationType)) {
			workOrder = flowOutHandle(optation, workOrderDto, workOrder,workOrderRelation);
		}
		// 结案
		else if (WorkOrderProcessButton.END.equals(oprationType)) {
			Integer nodeHandleStatus = getNodeHandleStatus(workOrder);
			workOrder.setStatusId(nodeHandleStatus);
			taskTimeOutRecordDao.deleteByProcessInstanceId(workOrder.getProcessInstanceId());
		}
		return workOrder;
	}

	/**
	 * TODO 更新工单字段信息
	 * @author:
	 * @createtime: 2021/3/5 13:38
	 * @param workOrder
	 * @param workOrderDto
	 * @return: workOrder
	 */
	private WorkOrder setWorkOrderCustomField(WorkOrderDto workOrderDto, WorkOrder workOrder){
		TaskForm taskForm = taskFormDao.getByTaskId(workOrderDto.getStartFormInputDto().getTaskId());
		if (null != taskForm) {
			JSONObject content = taskForm.getContent();
			JSONObject modelValue = content.getJSONObject("modelValue");
			Map<String, Object> innerMap = modelValue.getInnerMap();
			JSONObject customField = workOrder.getCustomField();
			Map<String, Object> cusMap = customField.getInnerMap();
			String st = "";
			for (String str : innerMap.keySet()) {
				for (String s : cusMap.keySet()) {
					if (str.equals(s)) {
						if (innerMap.get(str) instanceof Collection) {
							for (Object s1 : (Collection)innerMap.get(str)) {
								st += s1 + "/";
							}
							st = st.substring(0, st.length() - 1);
							cusMap.put(s, st);
						} else {
							cusMap.put(s, innerMap.get(str));
						}
					}
				}
			}
			JSONObject jsonObject = new JSONObject(cusMap);
			workOrder.setCustomField(jsonObject);
		}
		return workOrder;
	}

	private Integer getNodeHandleStatus(WorkOrder workOrder) {
		Long currentWorkOrderNodeId = workOrder.getCurrentWorkOrderNodeId();
		WorkOrderTypeNodeVo workOrderTypeNodeVo = workOrderTypeNodeDao.getNodeByWorkOrderNodeId(currentWorkOrderNodeId);
		JSONObject nodeVoContent = workOrderTypeNodeVo.getContent();
		JSONArray sequenceFlows = nodeVoContent.getJSONArray("sequenceFlows");
		Integer status=null;
		for (int i = 0; i <sequenceFlows.size() ; i++) {
			JSONObject jsonObject = sequenceFlows.getJSONObject(i);
			String type = jsonObject.getString("type");
			if (WorkOrderProcessButton.END.equals(type)){
				status = jsonObject.getInteger("status");
			}
		}
		return status;
	}


	/**
	 * @Author: Donny_dong
	 * @Description: 转出处理
	 * @Param:
	 * @return:
	 * @Date: 2020/5/12
	 */
	private WorkOrder flowOutHandle(JSONObject optation, WorkOrderDto workOrderDto, WorkOrder workOrder, WorkOrderRelation workOrderRelation) {
		workOrderDto.setProcessInstanceId(workOrder.getProcessInstanceId());
		Long targetRef = optation.getLong("targetRef");
		WorkOrderTypeNodeVo workOrderTypeNodeVo = workOrderTypeNodeDao.selectById(targetRef);
		JSONObject nodeVoContent = workOrderTypeNodeVo.getContent();
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("workOrderId", workOrder.getId());
		jsonObject.put("CHANL_PRI_ID",workOrderRelation.getExternalWorkOrderId());
		jsonObject.put("SESSION_ID",workOrderRelation.getSessionId());
//		jsonObject.put("currentWorkOrderNodeId", targetRef);
//		jsonObject.put("externalFlowType",FieldEnum.FLOW_OUT.getCode());
		log.info("工单创建后转出时的必传参数为:" + workOrder.getId(), targetRef);
		jsonObject = assembleExternalParam(workOrderDto, jsonObject);
		//调用转出接口，后期需要完善具体调用过程
		String flowOutUrl = nodeVoContent.getJSONObject("flowOutApi").getString("getAddress");
		String httpHeaderStr = nodeVoContent.getJSONObject("flowOutApi").getString("headers");
		JSONObject httpHeader = JSON.parseObject(httpHeaderStr);
		JSONObject requestResult = eripDataSynService.externalWorkOrderFlowOut(flowOutUrl, jsonObject, httpHeader);
		String code = requestResult.getString("CODE");
		String desc = requestResult.getString("DESC");
		JSONObject data = requestResult.getJSONObject("DATA");
		String appNo =null;
		String QMTSign = null;
		if (!Objects.isNull(data)){
			appNo = data.getString("APP_NO");
			QMTSign = data.getString("CHANL_PRI_ID");
		}
		log.info("解析erip返回的数据："+"code:"+code+" desc:"+desc+" appNo:"+appNo+" QMTSign:"+QMTSign);
		workOrder.setFailDescription(desc);
		workOrder.setAppNo(appNo);
		workOrder.setChengRanResultSign(code);
		workOrder.setQMTSign(QMTSign);
		ActCommonUtils.arbitraryJump(workOrderTypeNodeVo.getName() + targetRef, workOrder.getProcessInstanceId());
		workOrder.setCurrentHandlerId("");
		workOrder.setCurrentHandlerName("");
		workOrder.setCurrentWorkOrderNodeId(workOrderTypeNodeVo.getId());
		workOrder.setCurrentWorkOrderNodeName(workOrderTypeNodeVo.getName());
		return workOrder;
	}

	/**
	 * TODO 记录处理日志
	 * @author: victor_tang
	 * @createtime: 2020/5/25 13:31
	 * @param workOrder 1
	 * @param userId 2
	 * @param opration 3
	 * @return: void
	 */
	private void recordHandleLog(WorkOrder workOrder, String userId, JSONObject opration,WriteFormTemplateInputDto writeFormTemplateInputDto) {
		WorkOrderLog workOrderLog = new WorkOrderLog();
		if (Objects.nonNull(writeFormTemplateInputDto)){
			Map modelValue = writeFormTemplateInputDto.getModelValue();
			String jsonString = JSON.toJSONString(modelValue);
			JSONObject nodeModelValue = JSON.parseObject(jsonString);
			workOrderLog.setNodeModelValue(nodeModelValue);
		}

		workOrderLog.setWorkOrderId(workOrder.getId());
		workOrderLog.setWorkOrderNodeId(opration.getLong("sourceRef"));
		Integer workOrderStatusId = workOrder.getStatusId();
		workOrderLog.setLogType(opration.getString("name"));
		workOrderLog.setWorkOrderStatusId(workOrderStatusId);
		workOrderLog.setLogCreaterId(userId);
		EwsUser ewsUser = ewsUserDao.selectById(userId);
		if (Objects.nonNull(ewsUser)) {
			EwsDepartmentVo ewsDepartmentVo = ewsDepartmentDao.selectByPrimaryKeyAndTenantId(ewsUser.getDepartmentId(),ewsUser.getTenantId());
			workOrderLog.setLogCreaterName(ewsUser.getName());
			workOrderLog.setLogCreaterDept(ewsDepartmentVo != null ? ewsDepartmentVo.getName() : "");
		}
		workOrderLog.setTenantId(workOrder.getTenantId());
		workOrderLog.setLogCreateTime(new Date(System.currentTimeMillis()));
		workOrderLog.setContent(workOrder.getLogContent());
		workOrderLogService.addSave(workOrderLog);
	}

	/**
	 * TODO 获取历史处理人
	 * @author: victor_tang
	 * @createtime: 2020/5/25 13:32
	 * @param historyHandlerId 1
	 * @return: java.lang.String
	 */
	private String getHistoryHandler(String historyHandlerId) {
		if (StringUtils.isEmpty(historyHandlerId)) {
			return historyHandlerId;
		}
		List<String> historyHandlerIds = Arrays.asList(historyHandlerId.split(","));
		HashMap<String, Object> hashMap = new HashMap<>(2);
		hashMap.put("userIds", historyHandlerIds);
		List<EwsUser> ewsUsers = ewsUserDao.selectAllUserList(hashMap);
		List<String> historyHandlerNames = ewsUsers.stream().map(ewsUser -> ewsUser.getName()).collect(Collectors.toList());
		String historyHandlerName = StringUtils.join(historyHandlerNames, ",");
		return historyHandlerName;
	}

	/**
	 * TODO 修改当前表单信息
	 * @author: victor_tang
	 * @createtime: 2020/5/25 13:32
	 * @param workOrderDto 1
	 * @return: void
	 */
	private void updateCurrentTaskForm(WorkOrderDto workOrderDto) {
		// 更新表单
		String currentTaskId = workOrderDto.getWriteFormTemplateInputDto().getTaskId();
		TaskForm taskForm = taskFormDao.getByTaskId(currentTaskId);
		taskForm.setSubmitTime(new Timestamp(System.currentTimeMillis()));
		Object modelValue = workOrderDto.getWriteFormTemplateInputDto().getModelValue();
		Map<String, Object> modelMap = null;
		if (modelValue != null) {
			modelMap = (Map<String, Object>) modelValue;
		}
		JSONObject content = workOrderDto.getWriteFormTemplateInputDto().getContent();
		content = resetConten(modelMap, content);
		taskForm.setContent(content);
		taskFormDao.update(taskForm);
	}
	/**
	 * TODO 更新表单content内容
	 * @author: victor_tang
	 * @createtime: 2020/5/25 13:33
	 * @param modelMap 1
	 * @param content 2
	 * @return: com.alibaba.fastjson.JSONObject
	 */
	private JSONObject resetConten(Map<String, Object> modelMap, JSONObject content) {
		JSONArray jsonArray = content.getJSONArray("list");
		for (int i = 0; i < jsonArray.size(); i++) {
			JSONObject jsonObject = jsonArray.getJSONObject(i);
			if ("grid".equals(jsonObject.getString("type"))) {
				JSONArray jsonArrayGrid = jsonObject.getJSONArray("columns");
				for (int j = 0; j < jsonArrayGrid.size(); j++) {
					JSONObject jsonObject2 = jsonArrayGrid.getJSONObject(j);
					JSONArray jsonArray2 = jsonObject2.getJSONArray("list");
					for (int k = 0; k < jsonArray2.size(); k++) {
						JSONObject jsonObject3 = jsonArray2.getJSONObject(k);
						String model = jsonObject3.getString("model");
						String defaultValue = jsonObject3.getJSONObject("options").getString("defaultValue");
						for (String key : modelMap.keySet()) {
							if (key.equals(model)) {
								defaultValue = modelMap.get(key).toString();
								jsonObject3.getJSONObject("options").put("defaultValue", defaultValue);
							}
						}
					}
				}

			} else {
				String model = jsonObject.getString("model");
				for (String key : modelMap.keySet()) {
					if (key.equals(model)) {
						jsonObject.getJSONObject("options").put("defaultValue", modelMap.get(key));
					}
				}
			}

		}
		return content;
	}

	/**
	 * TODO 修改原始表单
	 * @author: victor_tang
	 * @createtime: 2020/5/25 13:33
	 * @param workOrderDto 1
	 * @return: void
	 */
	private void updateStartTaskForm(WorkOrderDto workOrderDto) {
		String startNodeTaskId = workOrderDto.getStartFormInputDto().getTaskId();
		if (StringUtils.isEmpty(startNodeTaskId)) {
			log.info("传入的初始节点任务id为空！");
			return;
		}
		TaskForm startNodetaskForm = taskFormDao.getByTaskId(startNodeTaskId);
		if (startNodetaskForm==null) {
			log.info("未找到"+startNodeTaskId+"任务表单信息！");
			return;
		}
		JSONObject startNodecontent = workOrderDto.getStartFormInputDto().getContent();
		System.err.println("================================");
		startNodetaskForm.setContent(startNodecontent);
		taskFormDao.update(startNodetaskForm);
	}

	/**
	 * TODO 设置工单处理人信息
	 *
	 * @param workOrder
	 * @param workOrderTypeNodeVo
	 * @return
	 */
	private WorkOrder setTiaoZhuanWorkOrderHandlePersonInfo(WorkOrder workOrder,
															WorkOrderTypeNodeVo workOrderTypeNodeVo) {
		// 工单派发模式为依次自动派发时
		if (WorkOrderDistributionWay.SEQUENCE_DISTRIBUTION.equals(workOrderTypeNodeVo.getDistributeWay())) {
			return setAutoDistributeWorkOrderHandlePersonInfo(workOrder, workOrderTypeNodeVo);
		}

		// 工单当前处理人
		JSONObject nodeContent = workOrderTypeNodeVo.getContent();
		// 处理人类型
		String assigneeType = nodeContent.getString("assigneetype");
		List<String> assignee = null;
		if (ConstantCode.UserRoleDeptType.DEPT.equals(assigneeType)) {
			JSONArray assigneeArray = nodeContent.getJSONArray("assignee");
			JSONArray deptUserValue = nodeContent.getJSONArray("deptUserValue");
			if (CollectionUtils.isEmpty(deptUserValue)) {
				assignee = commonUtil.splitDeptCode(assigneeArray.toJSONString());
			}else {
				assignee = JSON.parseArray(deptUserValue.toJSONString(), String.class);
				assigneeType = UserRoleDeptType.USER;
			}
		} else {
			assignee = nodeContent.getObject("assignee", List.class);
		}
		assignee = CommonUtil.handleCurrentCreator(assignee,workOrder);
		// 获取处理人信息
		List<EwsUser> ewsUsersList = userService.getUserListByTypeAndTypeIds(assigneeType,
				assignee, workOrder.getTenantId());
		if (CollectionUtils.isEmpty(ewsUsersList)) {
			throw new RuntimeException(
					"流转的目标节点设置的处理人角色,部门下没有用户，或设置的处理人已被删除，无法设置工单处理人，请检查工单流程配置！");
		}
		List currentHandlerUserIds = new ArrayList<String>();
		List currentHandlerUserNames = new ArrayList<String>();
//		if (!CollectionUtils.isEmpty(ewsUsersList)) {
		for (EwsUser ewsUser : ewsUsersList) {
			currentHandlerUserIds.add(ewsUser.getId());
			currentHandlerUserNames.add(ewsUser.getName());
		}
		workOrder.setCurrentHandlerId(StringUtils.join(currentHandlerUserIds, ","));
		workOrder.setCurrentHandlerName(StringUtils.join(currentHandlerUserNames, ","));
//		} else {
//			workOrder.setCurrentHandlerId(workOrder.getCreateUserId());
//			workOrder.setCurrentHandlerName(workOrder.getCreateUserName());
//		}
		return workOrder;
	}

	/**
	 * TODO 设置工单处理人信息
	 *
	 * @param workOrder
	 * @param redeploy
	 * @return
	 */
	private WorkOrder setZhuanPaiWorkOrderHandlePersonInfo(WorkOrder workOrder, Redeploy redeploy) {
		Long targetNodeId = redeploy.getTargetNodeId();
		WorkOrderTypeNodeVo workOrderTypeNodeVo = workOrderTypeNodeDao.getNodeByWorkOrderNodeId(targetNodeId);
//		// 工单派发模式为依次自动派发时
////		if (WorkOrderDistributionWay.SEQUENCE_DISTRIBUTION.equals(workOrderTypeNodeVo.getDistributeWay())) {
////			return setAutoDistributeWorkOrderHandlePersonInfo(workOrder, workOrderTypeNodeVo);
////		}
		// 获取处理人信息
		List<String> roleIds = null;
		if (ConstantCode.UserRoleDeptType.DEPT.equals(redeploy.getRoleType())) {
			JSONArray roleIdList = redeploy.getValue();
			roleIds = commonUtil.splitDeptCode(roleIdList.toJSONString());
		} else {
			JSONArray roleIdList = redeploy.getValue();
			roleIds = JSONArray.parseArray(roleIdList.toJSONString(), String.class);
		}
		roleIds = CommonUtil.handleCurrentCreator(roleIds,workOrder);
		List<EwsUser> ewsUsersList = userService.getUserListByTypeAndTypeIds(redeploy.getRoleType(),
				roleIds, workOrder.getTenantId());
		if (CollectionUtils.isEmpty(ewsUsersList)) {
			throw new RuntimeException(
					"流转的目标节点设置的处理人角色,部门下没有用户，或设置的处理人已被删除，无法设置工单处理人，请检查工单流程配置！");
		}
		List currentHandlerUserIds = new ArrayList<String>();
		List currentHandlerUserNames = new ArrayList<String>();
		for (EwsUser ewsUser : ewsUsersList) {
			currentHandlerUserIds.add(ewsUser.getId());
			currentHandlerUserNames.add(ewsUser.getName());
		}
		workOrder.setCurrentHandlerId(StringUtils.join(currentHandlerUserIds, ","));
		workOrder.setCurrentHandlerName(StringUtils.join(currentHandlerUserNames, ","));
		return workOrder;
	}

	/**
	 * TODO 设置自动派发模式工单处理人信息
	 *
	 * @param workOrder           1
	 * @param workOrderTypeNodeVo 2
	 * @author: victor_tang
	 * @createtime: 2020/2/3 14:07
	 * @return: com.egoo.ews.service.vo.WorkOrder
	 */
	private WorkOrder setAutoDistributeWorkOrderHandlePersonInfo(WorkOrder workOrder, WorkOrderTypeNodeVo workOrderTypeNodeVo) {
		JSONObject content = workOrderTypeNodeVo.getContent();
		String lastDistributeUserId = workOrderTypeNodeVo.getLastDistributeUserId();
		String assigneetype = content.getString("assigneetype");
		List<String> assigneeList = content.getObject("assignee", List.class);
		List<EwsUser> ewsUsersList = userService.getUserListByTypeAndTypeIds(assigneetype, assigneeList, workOrder.getTenantId());
		if (ewsUsersList != null && ewsUsersList.size() > 0) {
			int lastIndex = ewsUsersList.size() - 1;
			// 工单最后分派人为空或者为最后一人时，下一个分派人都是第一个人
			if (StringUtils.isEmpty(lastDistributeUserId)
					|| lastDistributeUserId.equals(ewsUsersList.get(lastIndex).getId())) {
				workOrder.setCurrentHandlerId(ewsUsersList.get(0).getId());
				workOrder.setCurrentHandlerName(ewsUsersList.get(0).getName());
				// 更新工单类型节点最后分派人id
				workOrderTypeNodeVo.setLastDistributeUserId(ewsUsersList.get(0).getId());
				workOrderTypeNodeDao.updateByPrimaryKeySelective(workOrderTypeNodeVo);
				return workOrder;
			}
			// 循环依次分派
			for (int i = 0; i < ewsUsersList.size(); i++) {
				if (lastDistributeUserId.equals(ewsUsersList.get(i).getId())) {
					workOrder.setCurrentHandlerId(ewsUsersList.get(i + 1).getId());
					workOrder.setCurrentHandlerName(ewsUsersList.get(i + 1).getName());
					// 更新工单类型节点最后分派人id
					workOrderTypeNodeVo.setLastDistributeUserId(ewsUsersList.get(i + 1).getId());
					workOrderTypeNodeDao.updateByPrimaryKeySelective(workOrderTypeNodeVo);
					return workOrder;
				}
			}

		}
		return workOrder;
	}

	/**
	 * TODO 批量删除工单
	 *
	 * @param workOrderList
	 * @return
	 */
	@Override
	public Integer deleteBatch(List<WorkOrder> workOrderList, String userId) {
//		Integer result = workOrderDao.deleteBatch(workOrderList);
		Integer result = 1;
		for (int i = 0; i < workOrderList.size(); i++) {
			result += workOrderDao.updateWorkOrder(workOrderList.get(i));
			// 删除超时任务记录
			taskTimeOutRecordDao.deleteByProcessInstanceId(workOrderList.get(i).getProcessInstanceId());
		}
		log.info("deleteBatch: {}", workOrderList);
		for (WorkOrder workOrder : workOrderList) {
			workOrder = workOrderDao.selectById(workOrder.getId());
			JSONObject jsonObject = new JSONObject();
			jsonObject.put("name", WorkOrderLogType.DELETE_ORDER_CODE);
			recordHandleLog(workOrder, userId, jsonObject,new WriteFormTemplateInputDto());
		}
		return result;
	}

	/**
	 * TODO 批量关闭工单
	 * @author: victor_tang
	 * @createtime: 2020/5/20 13:43
	 * @param workOrderList 1
	 * @param userId 2
	 * @return: java.lang.Integer
	 */
	@Override
	public Integer closeBatch(List<WorkOrder> workOrderList, String userId) {
		Integer result = 1;
		for (int i = 0; i < workOrderList.size(); i++) {
			WorkOrder workOrder = workOrderList.get(i);
			workOrder.setStatusId(WorkOrderState.ALREDAY_CLOSE);
			result += workOrderDao.updateWorkOrder(workOrder);
			workOrder = workOrderDao.selectById(workOrder.getId());
			// 删除超时任务记录
			taskTimeOutRecordDao.deleteByProcessInstanceId(workOrder.getProcessInstanceId());
			JSONObject jsonObject = new JSONObject();
			jsonObject.put("name", WorkOrderLogType.CLOSE_ORDER_CODE);
			recordHandleLog(workOrder, userId, jsonObject,new WriteFormTemplateInputDto());
			mqCommonUtil.pushToMsgTriggerQueue(workOrder.getId());
		}
		log.info("closeBatch: {}", workOrderList);
		return result;
	}

	/**
	 * TODO 获取创建节点的信息
	 * @author: victor_tang
	 * @createtime: 2020/5/20 13:43
	 * @param workOrderTypeId 1
	 * @return: com.egoo.ews.service.pojo.dto.WorkOrderCreateNodeDto
	 */
	@Override
	public WorkOrderCreateNodeDto getCreateNode(Long workOrderTypeId,Integer formTemplateId) {
		WorkOrderCreateNodeDto workOrderCreateNodeDto = new WorkOrderCreateNodeDto();
		log.info("传入的类型id为："+workOrderTypeId);
		WorkOrderTypeNodeVo startNode = workOrderTypeNodeDao.selectStartNodeByWorkOrderTypeId(workOrderTypeId);
		// 节点名字
		Long nodeId = startNode.getId();
		String nodeName = startNode.getName();
		workOrderCreateNodeDto.setNodeId(nodeId);
		workOrderCreateNodeDto.setNodeName(nodeName);
		// 节点的表单模板
		JSONObject formTemplate = provideFormTemplateForCreateWorkOrder(startNode, formTemplateId);
//		Integer formTemplateId = startNode.getFormTemplateId();
//		FormTemplate formTemplate = formTemplateDao.selectContentById(formTemplateId);
		workOrderCreateNodeDto.setFormTemplate(formTemplate);
		// 节点能执行的动作
		JSONArray sequenceFlows = startNode.getContent().getJSONArray("sequenceFlows");
		workOrderCreateNodeDto.setSequenceFlows(sequenceFlows);
		log.info("getCreateNode: {}", workOrderCreateNodeDto);
		return workOrderCreateNodeDto;
	}
	/**
	 * @Author: Donny_dong
	 * @Description: 为创建工单提供模板
	 * @Param:
	 * @return:
	 * @Date: 2020/5/21
	 */
	private JSONObject provideFormTemplateForCreateWorkOrder(WorkOrderTypeNodeVo startNode, Integer formTemplateId) {
		JSONObject formTempalteContent = startNode.getFormTempalteContent();
		//页面完善后，判断标识加入数据库，下面的判断需要替换
		if (formTemplateId !=null){
			JSONArray listFormTemplate = formTempalteContent.getJSONArray("list");
			for (int i = 0; i <listFormTemplate.size() ; i++) {
				JSONObject formTemplate = listFormTemplate.getJSONObject(i);
				Integer formId = formTemplate.getInteger("formId");
				if (formTemplateId.equals(formId)){
					return formTemplate;
				}
			}
		}
		return formTempalteContent;
	}


	/**
	 * TODO 根据工单id获取工单信息
	 *
	 * @param workOrderId
	 * @return
	 */
	@Override
	public WorkOrder selectById(String workOrderId) {
		WorkOrder workOrder = workOrderDao.selectById(workOrderId);
		log.info("selectById: {}", workOrder);
		return workOrder;
	}

	/**
	 * TODO 更新工单信息
	 *
	 * @param workOrder
	 * @return
	 */
	@Override
	public Integer updateWorkOrder(WorkOrder workOrder) {
		return workOrderDao.updateWorkOrder(workOrder);
	}

	/**
	 * TODO 获取所有的启用状态的工单类型名字（包含全部）
	 *
	 * @return
	 */
	@Override
	public List<InteractiveDataVo> selectAllOpenWorkOrderTypeName(String tenantId) {
		List<InteractiveDataVo> interactiveDataList = new ArrayList<>();
		InteractiveDataVo interactiveData = new InteractiveDataVo();
		interactiveData.setValue(ConstantCode.UserRoleDeptType.ALL);
		interactiveData.setLabel(UserRoleDeptType.ALL_ZH);
		interactiveDataList.add(interactiveData);
		List<InteractiveDataVo> interactiveDataList1 = workOrderTypeDao.selectAllWorkOrderTypeName(tenantId);
		interactiveDataList.addAll(interactiveDataList1);
		return interactiveDataList;
	}

	/**
	 * TODO 获取所有的工单状态名字（包含全部但不包括状态不变）
	 *
	 * @return
	 */
	@Override
	public List<InteractiveDataVo> selectAllWorkOrderStatusName(String tenantId) {
		List<InteractiveDataVo> interactiveDataList = new ArrayList<>();
		InteractiveDataVo interactiveData = new InteractiveDataVo();
		// 0代表查询全部
		interactiveData.setValue(WorkOrderState.ALL);
		interactiveData.setLabel(UserRoleDeptType.ALL_ZH);
		interactiveDataList.add(interactiveData);
		List<InteractiveDataVo> interactiveDataList1 = workOrderStatusDao.selectAllWorkOrderStatusName(tenantId);
		interactiveDataList.addAll(interactiveDataList1);
		return interactiveDataList;
	}

	/**
	 * TODO 根据字段和排序标识查询工单
	 *
	 * @return
	 */
	@Override
	public List<WorkOrder> selectByfieldAndSortTag(String field, Integer sortTag) {
		String sql = "";
		String fileds = null;
		String sortTags = null;
		if ("id".equals(field)) {
			fileds = "id";
			// 0为正序
			if (sortTag == 0) {
				sortTags = "ASC";
				// 1为逆序
			} else {
				sortTags = "DESC";
			}
		} else if ("title".equals(field)) {
			fileds = "title";
			// 0为正序
			if (sortTag == 0) {
				sortTags = "ASC";
				// 1为逆序
			} else {
				sortTags = "DESC";
			}
		} else if ("statusId".equals(field)) {
			fileds = "status_id";
			// 0为正序
			if (sortTag == 0) {
				sortTags = "ASC";
				// 1为逆序
			} else {
				sortTags = "DESC";
			}
		} else if ("workOrderTypeId".equals(field)) {
			fileds = "work_order_type_id";
			// 0为正序
			if (sortTag == 0) {
				sortTags = "ASC";
				// 1为逆序
			} else {
				sortTags = "DESC";
			}
		} else if ("priority".equals(field)) {
			fileds = "priority";
			// 0为正序
			if (sortTag == 0) {
				sortTags = "ASC";
				// 1为逆序
			} else {
				sortTags = "DESC";
			}
		} else if ("source".equals(field)) {
			fileds = "source";
			// 0为正序
			if (sortTag == 0) {
				sortTags = "ASC";
				// 1为逆序
			} else {
				sortTags = "DESC";
			}
		} else if ("clientName".equals(field)) {
			fileds = "client_name";
			// 0为正序
			if (sortTag == 0) {
				sortTags = "ASC";
				// 1为逆序
			} else {
				sortTags = "DESC";
			}
		} else if ("currentHandlerId".equals(field)) {
			fileds = "current_handler_id";
			// 0为正序
			if (sortTag == 0) {
				sortTags = "ASC";
				// 1为逆序
			} else {
				sortTags = "DESC";
			}
		} else if ("createTime".equals(field)) {
			fileds = "create_time";
			// 0为正序
			if (sortTag == 0) {
				sortTags = "ASC";
				// 1为逆序
			} else {
				sortTags = "DESC";
			}
		} else {
			fileds = "last_update_time";
			// 0为正序
			if (sortTag == 0) {
				sortTags = "ASC";
				// 1为逆序
			} else {
				sortTags = "DESC";
			}
		}
		sql = "select * from work_order ORDER BY" + " " + fileds + " " + sortTags;
		List<WorkOrder> workOrderList = workOrderDao.executeSql(sql);
		return workOrderList;
	}

	/**
	 * TODO 上传附件
	 *
	 * @param file 1
	 * @author: victor_tang
	 * @createtime: 2020/3/9 19:34
	 * @return: com.egoo.ews.service.dto.UploadFileDto
	 */
	@Override
	public JSONObject uploadFile(MultipartFile file, String tenantId) {
		JSONObject jsonObject = new JSONObject();
		String originalFilename = file.getOriginalFilename();
		File myFile = commonUtil.multipartFileToFile(file);
		try {
			if (StringUtils.isEmpty(originalFilename)) {
				jsonObject.put("error", "附件名称不能为空！");
				return jsonObject;
			}
			String fileType = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
			String uploadUrl = fileServerUrl+"/put?" + "filechannel=webchat" +
					"&filetype" +
					"=" + fileType + "&tenantid=" + tenantId + "";
			HttpHeaders httpHeaders = new HttpHeaders();
			MediaType type = MediaType.parseMediaType("multipart/form-data");
			httpHeaders.setContentType(type);
			httpHeaders.add("Referer", "127.0.0.1");
			FileSystemResource fileSystemResource = new FileSystemResource(myFile.getPath());
			MultiValueMap<String, Object> form = new LinkedMultiValueMap<>();
			form.add("file", fileSystemResource);
			form.add("filename",originalFilename);
			org.springframework.http.HttpEntity<MultiValueMap<String, Object>> httpEntity = new org.springframework.http.HttpEntity<>(form,httpHeaders);
			String result = restTemplate.postForObject(uploadUrl, httpEntity, String.class);
			String downloadUrl = fileServerHttpsUrl+"/get?" + "filename=" + result;
			log.info("最终附件下载地址：" + downloadUrl);
			jsonObject.put("url", downloadUrl);
		} catch (Exception e) {
			log.error("上传附件异常：" + e);
			jsonObject.put("error", "上传附件异常！" + e);
		} finally {
			deleteLocalFile(myFile);
		}
		return jsonObject;
	}

	/**
	 * @Author: Donny_dong
	 * @Description: 删除本地缓存的文件
	 * @Param:
	 * @return:
	 * @Date: 2020/8/11
	 */
	private void deleteLocalFile(File myFile) {
		if (!myFile.exists()){
			return;
		}
		myFile.delete();
	}

	/**
	 * TODO 创建或更新任务表单信息
	 * @author: victor_tang
	 * @createtime: 2020/5/25 11:09
	 * @param ewsUser 1
	 * @param processInstanceId 2
	 * @param taskId 3
	 * @param workOrderDto 4
	 * @param currentStatusId 5
	 * @return: java.lang.Integer
	 */
	public Integer createOrUpdateFormTemplate(EwsUser ewsUser,String processInstanceId,
											  String taskId,WorkOrderDto workOrderDto,
											  Integer currentStatusId) {
		WriteFormTemplateInputDto writeFormTemplateInputDto = workOrderDto.getWriteFormTemplateInputDto();
		TaskForm taskFormInfo = taskFormDao.getByTaskId(taskId);
		JSONObject content = writeFormTemplateInputDto.getContent();
		// 创建任务表单
		TaskForm taskForm = new TaskForm();
		taskForm.setTaskId(taskId);
		taskForm.setProcessInstanceId(processInstanceId);
		taskForm.setHandlerId(ewsUser.getId());
		taskForm.setHandlerName(ewsUser.getName());
		taskForm.setNodeId(writeFormTemplateInputDto.getNodeId());
		taskForm.setNodeName(writeFormTemplateInputDto.getNodeName());
		taskForm.setSubmitTime(new Timestamp(System.currentTimeMillis()));
		taskForm.setTenantId(workOrderDto.getTenantId());
		//获取创建此任务时的节点工单状态
		taskForm = getTaskFormNodeInfo(taskForm, currentStatusId);
		taskForm.setContent(content);
		if (taskFormInfo == null) {
			List<TaskForm> taskForms = taskFormDao.selectByProcessInstanceId(processInstanceId);
			String taskSign=null;
			JSONObject nodeInfo=null;
			TaskForm taskFormLate =null;
			if (!CollectionUtils.isEmpty(taskForms)&&taskForms.size()>1) {
				taskFormLate = taskForms.get(taskForms.size() - 1);
				nodeInfo = taskFormLate.getNodeInfo();
				taskSign=nodeInfo.getString("taskSign");
				if ("unNormal".equals(taskSign)){
					nodeInfo.put("taskSign","normal");
					taskForm.setNodeInfo(nodeInfo);
					taskForm.setTaskId(taskFormLate.getTaskId());
					return taskFormDao.update(taskForm);
				}
			}

			return taskFormDao.create(taskForm);
		}
//		else if(taskForm !=null && taskForm.getNodeInfo().getString("withdraw").equals("Y")){
//			return taskFormDao.create(taskForm);
//		}
//		if (WorkOrderState.ORDER_WAIT_CHECK == currentStatusId) {
//				// 工单状态为，不更待检查时新当前节点状态信息，避免驳回工单后状态异常
//				taskForm.setNodeInfo(taskFormInfo.getNodeInfo());
//		}
		return taskFormDao.update(taskForm);
	}
	/**
	 * @Author: Donny_dong
	 * @Description: 获取该任务的节点状态信息
	 * @Param:
	 * @return:
	 * @Date: 2020/2/12
	 */
	private TaskForm getTaskFormNodeInfo(TaskForm taskForm, Integer currentStatusId) {
		// 工单状态为待检查时，不更新当前节点状态信息，避免驳回工单后状态异常
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("nodeStatus", currentStatusId);
		jsonObject.put("withdraw", ConstantCode.N);
		taskForm.setNodeInfo(jsonObject);
		return taskForm;
	}

	/**
	 * TODO 获取转派时的所有可选节点
	 *
	 * @param workOrderTypeId
	 * @return
	 */
	@Override
	public List<NodeIdAndNameDto> getSelectableNodes(Long workOrderTypeId, Long nodeId) {
		// 获取节点所属版本号
		WorkOrderTypeNodeVo nodeInfo = workOrderTypeNodeDao.getNodeByWorkOrderNodeId(nodeId);
		log.info("获取的工单类型节点"+nodeId+"信息{}"+nodeInfo);
		if (nodeInfo==null) {
			throw new RuntimeException("工单类型节点信息为空，无法获取节点版本号！");
		}
		return workOrderTypeNodeDao.getSelectableNodes(workOrderTypeId, nodeInfo.getWorkOrderTypeVersion());
	}

	/**
	 * @return com.egoo.ews.service.utils.DBResponse
	 * @Author Donny_Dong
	 * @Description //TODO 工单改派
	 * @Date 18:16 2020/1/17
	 * @Param [workOrderDto]
	 **/
	@Override
	public DbResponse updateCurrentHandler(WorkOrderDto workOrderDto) {
		String roleType = workOrderDto.getRoleType();
		String tenantId = workOrderDto.getTenantId();
//		String workOrderStatus = workOrderDto.getWorkOrderStatus();
		List<String> roleIds = null;
		if (ConstantCode.UserRoleDeptType.DEPT.equals(roleType)) {
			JSONArray roleIdList = workOrderDto.getRoleIdList();
			roleIds = commonUtil.splitDeptCode(roleIdList.toJSONString());
		} else {
			JSONArray roleIdList = workOrderDto.getRoleIdList();
			roleIds = JSONArray.parseArray(roleIdList.toJSONString(), String.class);
		}
		List<EwsUser> ewsUsers = userService.getUserListByTypeAndTypeIds(roleType, roleIds, tenantId);
		List<String> ids = ewsUsers.stream().map(ewsUser -> ewsUser.getId()).collect(Collectors.toList());
		List<String> names = ewsUsers.stream().map(ewsUser -> ewsUser.getName()).collect(Collectors.toList());
//		String processInstanceId = workOrderDto.getProcessInstanceId();
//		String taskId = ActTaskServiceUtil.getActiveTaskIdByProcessInstId(processInstanceId);
//		for (String currentHandlerId : ids) {
//			//修改流程引擎中的当前处理人
//			ActTaskServiceUtil.updateCurrentHandler(taskId, currentHandlerId);
//		}
		WorkOrder workOrder = workOrderDao.selectById(workOrderDto.getWorkOrderId());
		String oldCurrentHandlerId = workOrder.getCurrentHandlerId();
		String oldCurrentHandlerName = workOrder.getCurrentHandlerName();
		workOrder.setCurrentHandlerId(String.join(",", ids));
		String currentHandleName = String.join(",", names);
		workOrder.setCurrentHandlerName(currentHandleName);
		workOrder.setLastUserId(workOrderDto.getUserId());
		EwsUser ewsUser = ewsUserDao.selectById(workOrderDto.getUserId());
		workOrder.setLastUserName(ewsUser != null ? ewsUser.getName() : null);
		workOrder.setLastUpdateTime(new Timestamp(System.currentTimeMillis()));
		workOrder.setStatusId(Integer.valueOf(workOrderDto.getWorkOrderStatus()));
		workOrderDao.updateByPrimaryKeySelective(workOrder);
		String logContent = "工单处理人："+oldCurrentHandlerName+"==>"
						+currentHandleName+ConstantCode.REASSIGN_CONTENT_TAG+oldCurrentHandlerId;
		workOrder.setLogContent(logContent);
		workOrderDto.getOpration().put("name", WorkOrderLogType.REASSIGN_CODE);
		recordHandleLog(workOrder, workOrderDto.getUserId(), workOrderDto.getOpration(),workOrderDto.getWriteFormTemplateInputDto());
		// 推送工单id至mq
		mqCommonUtil.pushToMsgTriggerQueue(workOrderDto.getWorkOrderId());
		return new DbResponse(ResponseConstant.RES_SUCCESS_CODE, "当前处理人修改成功");
	}

	/**
	 * @return com.egoo.ews.service.utils.DBResponse
	 * @Author Donny_Dong
	 * @Description //TODO 外部创建工单
	 * @Date 14:52 2019/12/30
	 * @Param [jsonObject, workOrderDto]
	 **/
	@Transactional(rollbackFor = Exception.class)
	@Override
	public DbResponse externalCreate(JSONObject jsonObject, WorkOrderDto workOrderDto, List<WorkOrderFieldReflect> workOrderFieldReflects) {

		try {
			String createrId = jsonObject.getString("createrId");
			String createrName = jsonObject.getString("createrName");
			String userId = workOrderDto.getUserId();
			if (!StringUtils.isEmpty(workOrderDto.getCombineWorkOrderIds())) {
				combineWorkOrderHandle(workOrderDto);
			}
			Timestamp time = new Timestamp(System.currentTimeMillis());
			Long workOrderTypeId = workOrderDto.getWorkOrderTypeId();
			WorkOrderTypeVo workOrderTypeVo = workOrderTypeDao.selectById(workOrderTypeId);
			if (workOrderTypeVo == null) {
				return new DbResponse(ResponseConstant.RES_FAIL_CODE, "工单类型id错误或该流程不存在");
			}
			String workOrderTypeName = workOrderTypeVo.getName();
			JSONObject workOrderTypeVoContent = workOrderTypeVo.getContent();
			WorkOrder workOrder = new WorkOrder();

			ActiviVo activiVo = ActCommonUtils.startProcessInstance("_" + workOrderTypeName + workOrderTypeId, userId);
			String processInstanceId = activiVo.getProcessInstId();
			String taskId = activiVo.getTaskId();
			workOrder.setProcessInstanceId(processInstanceId);

			//创建工单前，先创建任务
			JSONObject newWorkOrderNodeInfo = workOrderTypeVoContent.getJSONObject("newworkordernodeInfo");
			Integer formTemplateId = Integer.parseInt(newWorkOrderNodeInfo.getString("formKey"));
			String nodeId = newWorkOrderNodeInfo.getString("uuid");
			String nodeName = newWorkOrderNodeInfo.getString("nodeName");
			String externalCreateNodeId = newWorkOrderNodeInfo.getString("externalCreateNodeId");
			String externalCreateStatus = newWorkOrderNodeInfo.getString("externalCreateStatus");
			TaskForm taskForm = new TaskForm();
			taskForm.setTaskId(taskId);
			taskForm.setProcessInstanceId(processInstanceId);
			taskForm.setHandlerId(createrId);
			taskForm.setHandlerName(createrName);
			taskForm.setNodeId(Long.parseLong(nodeId));
			taskForm.setNodeName(nodeName);
			taskForm.setTenantId(workOrderDto.getTenantId());
//			createTaskForm(taskForm, jsonObject, formTemplateId, workOrderFieldReflects);
			createTaskForm(taskForm, jsonObject, formTemplateId, workOrderDto);

//			数据组装，创建工单
			BeanUtils.copyProperties(workOrderDto, workOrder);
			WorkOrderTypeNodeVo workOrderTypeNodeVo = workOrderTypeNodeDao.getNodeByWorkOrderNodeId(Long.parseLong(externalCreateNodeId));
			workOrder.setCreateUserId(createrId);
			workOrder.setCreateUserName(createrName);
			workOrder.setStatusId(Integer.parseInt(externalCreateStatus));
			workOrder.setWorkOrderTypeId(workOrderTypeId);
			workOrder.setWorkOrderTypeName(workOrderTypeName);
			workOrder.setCurrentWorkOrderNodeId(workOrderTypeNodeVo.getId());
			workOrder.setCurrentWorkOrderNodeName(workOrderTypeNodeVo.getName());
			workOrder = getCurrentHandle(workOrderTypeNodeVo, workOrder);
			workOrder.setHistoryHandlerId(createrId);
			workOrder.setHistoryHandlerName(createrName);
			workOrder.setCreateUserId(createrId);
			workOrder.setCreateUserName(createrName);
			workOrder.setCreateTime(new Timestamp(System.currentTimeMillis()));
			workOrder.setLastUpdateTime(new Timestamp(System.currentTimeMillis()));
			workOrder.setProcessInstanceId(processInstanceId);
			workOrder.setTenantId(workOrderDto.getTenantId());
			workOrder.setDeleteStatus(0);

			WorkOrderRelation workOrderRelation = this.addWorkOrderRelation(workOrderDto);

			workOrder.setId(createCodeUtil.getWorkOrderId());
			ActCommonUtils.arbitraryJump(workOrderTypeNodeVo.getName() + externalCreateNodeId, processInstanceId);
			workOrderDao.create(workOrder);
			workOrderRelation.setWorkOrderId(workOrder.getId());
			workOrderRelation.setExternalWorkOrderId(workOrderDto.getExternalWorkOrderId());
			workOrderRelationMapper.insertWorkOrderRelation(workOrderRelation);

			JSONObject opration = new JSONObject();
			opration.put("sourceRef",nodeId);
			opration.put("name","外部创建");
			recordHandleLog(workOrder,userId,opration,new WriteFormTemplateInputDto());
//			saveLog(workOrder, nodeId, nodeName, userId);
			createExternalFlowInfo(workOrderDto);

		} catch (Exception e) {
			log.info("外部工单创建异常"+e);
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			return new DbResponse(ResponseConstant.RES_FAIL_CODE, "工单创建异常");
		}
		return new DbResponse(ResponseConstant.RES_SUCCESS_CODE, "创建成功");
	}


	/**
	 * @return void
	 * @Author Donny_Dong
	 * @Description //TODO 记录外部流转信息
	 * @Date 14:24 2020/1/6
	 * @Param [workOrderDto]
	 **/
	public void createExternalFlowInfo(WorkOrderDto workOrderDto) {
		ExternalFlowInfoVo externalFlowInfo = new ExternalFlowInfoVo();
		if (workOrderDto.getExternalFlowInfo() != null) {
			externalFlowInfo.setExternalFlowWorkOrderId(workOrderDto.getExternalWorkOrderId());
			externalFlowInfo.setExternalFlowInfo(workOrderDto.getExternalFlowInfo());
			externalFlowInfoDao.insert(externalFlowInfo);
		}
	}

	/**
	 * @return void
	 * @Author Donny_Dong
	 * @Description //TODO 外部工单创建log记录
	 * @Date 17:14 2019/12/31
	 * @Param [workOrder]
	 **/
	private void saveLog(WorkOrder workOrder, String nodeId, String nodeName, String userId) {
		try {
			WorkOrderLog workOrderLog = new WorkOrderLog();
			workOrderLog.setId(createCodeUtil.getUuid());
			workOrderLog.setWorkOrderId(workOrder.getId());
			workOrderLog.setWorkOrderNodeId(Long.parseLong(nodeId));
			workOrderLog.setWorkOrderNodeName(nodeName);
			workOrderLog.setWorkOrderStatusId(workOrder.getStatusId());
			workOrderLog.setLogCreateTime(new Timestamp(System.currentTimeMillis()));
			workOrderLog.setLogCreaterId(userId);
			workOrderLog.setLogType("外部创建");
			workOrderLog.setTenantId(workOrder.getTenantId());
			workOrderLogDao.insert(workOrderLog);
		} catch (NumberFormatException e) {
			log.error("工单log记录失败"+e);
			throw new RuntimeException();
		}

	}


	/**
	 * @return void
	 * @Author Donny_Dong
	 * @Description //TODO 获取处理人
	 * @Date 15:57 2019/12/31
	 * @Param [workOrderTypeNodeVo]
	 **/
	private WorkOrder getCurrentHandle(WorkOrderTypeNodeVo workOrderTypeNodeVo, WorkOrder workOrder) {
		JSONObject workOrderTypeNodeVoContent = workOrderTypeNodeVo.getContent();

		String assigneeType = workOrderTypeNodeVoContent.getString("assigneetype");
		if (StringUtils.isEmpty(assigneeType)){
			return workOrder;
		}
		List<String> assignee = null;
		if (ConstantCode.UserRoleDeptType.DEPT.equals(assigneeType)) {
			JSONArray assigneeArray = workOrderTypeNodeVoContent.getJSONArray("assignee");
			JSONArray deptUserValue = workOrderTypeNodeVoContent.getJSONArray("deptUserValue");
			if (CollectionUtils.isEmpty(deptUserValue)) {
				assignee = commonUtil.splitDeptCode(assigneeArray.toJSONString());
			}else {
				assignee = JSON.parseArray(deptUserValue.toJSONString(), String.class);
				assigneeType = UserRoleDeptType.USER;
			}
		} else {
			assignee = workOrderTypeNodeVoContent.getObject("assignee", List.class);
		}
		// 获取处理人信息
		List<EwsUser> ewsUsersList = userService.getUserListByTypeAndTypeIds(assigneeType,
				assignee, workOrder.getTenantId());
		StringBuffer stringBufferUserId = new StringBuffer();
		StringBuffer stringBufferUserName = new StringBuffer();
		for (EwsUser ewsUser : ewsUsersList) {
			stringBufferUserId.append(ewsUser.getId()).append(",");
			stringBufferUserName.append(ewsUser.getName()).append(",");
		}

		stringBufferUserId.deleteCharAt(stringBufferUserId.length() - 1);
		stringBufferUserName.deleteCharAt(stringBufferUserName.length() - 1);
		workOrder.setCurrentHandlerId(stringBufferUserId.toString());
		workOrder.setCurrentHandlerName(stringBufferUserName.toString());
		return workOrder;
	}

	/**
	 * @return void
	 * @Author Donny_Dong
	 * TODO 创建任务表单
	 * @Date 10:16 2019/12/31
	 * @Param [taskForm, jsonObject]
	 **/
	public void createTaskForm(TaskForm taskForm, JSONObject jsonObject, Integer formTemplateId, List<WorkOrderFieldReflect> workOrderFieldReflects) {

		try {
			FormTemplate formTemplate = formTemplateDao.selectById(formTemplateId);
			JSONObject formTemplateContent = formTemplate.getContent();
//			JSONArray formTemplateContentArray = formTemplateContent.getJSONArray(FormTemplateType.LIST);
//			for (int i = 0; i < formTemplateContentArray.size(); i++) {
//				JSONObject jsonObjectContent = formTemplateContentArray.getJSONObject(i);
//				if (FormTemplateType.GRID.equals(jsonObjectContent.getString(FormTemplateType.TYPE))) {
//					JSONArray jsonArrayColumns = jsonObjectContent.getJSONArray(FormTemplateType.COLUMNS);
//					for (int j = 0; j < jsonArrayColumns.size(); j++) {
//						JSONObject jsonObjectColumnsJsonObject = jsonArrayColumns.getJSONObject(j);
//						JSONArray jsonObjectColumnsJsonObjectArray = jsonObjectColumnsJsonObject.getJSONArray(FormTemplateType.LIST);
//						for (int k = 0; k < jsonObjectColumnsJsonObjectArray.size(); k++) {
//							JSONObject jsonObjectColumnsJsonObjectJSONArrayJSONObject = jsonObjectColumnsJsonObjectArray.getJSONObject(k);
//							String model = jsonObjectColumnsJsonObjectJSONArrayJSONObject.getString(FormTemplateType.MODEL);
//							JSONObject jsonObjectOptions = jsonObjectColumnsJsonObjectJSONArrayJSONObject.getJSONObject(FormTemplateType.OPTIONS);
//							for (WorkOrderFieldReflect workOrderFieldReflect :
//									workOrderFieldReflects) {
//								String innerFieldName = workOrderFieldReflect.getInnerFieldName();
//								String externalFieldName = workOrderFieldReflect.getExternalFieldName();
//								String defaultValue = null;
//								if (StringUtils.isEmpty(externalFieldName)) {
//									defaultValue = jsonObject.getString(innerFieldName);
//								} else {
//									defaultValue = jsonObject.getString(externalFieldName);
//								}
//								if (model.equals(innerFieldName)) {
//									jsonObjectOptions.put(FormTemplateType.DEFAULT_VALUE, defaultValue);
//								}
//							}
//						}
//					}
//				} else {
//					String model = jsonObjectContent.getString(FormTemplateType.MODEL);
//					JSONObject jsonObjectOptions = jsonObjectContent.getJSONObject(FormTemplateType.OPTIONS);
//					for (WorkOrderFieldReflect workOrderFieldReflect :
//							workOrderFieldReflects) {
//						String innerFieldName = workOrderFieldReflect.getInnerFieldName();
//						String externalFieldName = workOrderFieldReflect.getExternalFieldName();
//						String defaultValue = null;
//						if (StringUtils.isEmpty(externalFieldName)) {
//							defaultValue = jsonObject.getString(innerFieldName);
//						} else {
//							defaultValue = jsonObject.getString(externalFieldName);
//						}
//						if (model.equals(innerFieldName)) {
//							jsonObjectOptions.put(FormTemplateType.DEFAULT_VALUE, defaultValue);
//						}
//					}
//				}
//			}

			taskForm.setSubmitTime(new Timestamp(System.currentTimeMillis()));
			taskForm.setContent(formTemplateContent);
			taskFormDao.create(taskForm);
		} catch (Exception e) {
			log.info("创建任务表单异常");
			throw new RuntimeException();
		}
	}

	/**
	 * @return void
	 * @Author Donny_Dong
	 * TODO 创建任务表单
	 * @Date 10:16 2019/12/31
	 * @Param [taskForm, jsonObject]
	 **/
	public void createTaskForm(TaskForm taskForm, JSONObject jsonObject, Integer formTemplateId,WorkOrderDto workOrderDto) {

		try {
			FormTemplate formTemplate = formTemplateDao.selectById(formTemplateId);
			JSONObject formTemplateContent = formTemplate.getContent();
			formTemplateContent.put("modelValue",workOrderDto.getCustomField());
//
			taskForm.setSubmitTime(new Timestamp(System.currentTimeMillis()));
			taskForm.setContent(formTemplateContent);
			taskFormDao.create(taskForm);
		} catch (Exception e) {
			log.info("创建任务表单异常");
			throw new RuntimeException();
		}
	}
	/**
	 * @return com.egoo.ews.service.utils.DBResponse
	 * @Author Donny_Dong
	 * @Description //TODO 工单领取
	 * @Date 14:48 2020/1/17
	 * @Param [workOrderId, userId]
	 **/
	@Override
	public DbResponse workOrderRecieve(JSONObject jsonObject) {

		String userId = jsonObject.getString("userId");
		String workOrderId = jsonObject.getString("workOrderId");
		String processInstanceId = jsonObject.getString("processInstanceId");
		String distributeWay = jsonObject.getString("distributeWay");
		try {
			EwsUser ewsUser = ewsUserDao.selectById(userId);
			WorkOrderRelation workOrderRelation = new WorkOrderRelation();
			workOrderRelation.setWorkOrderId(workOrderId);
			workOrderRelation = workOrderRelationMapper.selectWorkOrderRelation(workOrderRelation);
			String taskId = ActTaskServiceUtil.getActiveTaskIdByProcessInstId(processInstanceId);
			ActTaskServiceUtil.updateCurrentHandler(taskId, userId);
			WorkOrder workOrder = new WorkOrder();
			workOrder.setId(workOrderId);
			workOrderRelation.setIsRecieve(FieldEnum.IS_RECIEVE.getCode());
			workOrder.setCurrentHandlerId(userId);
			workOrder.setCurrentHandlerName(ewsUser.getName());
			workOrderDao.updateByPrimaryKeySelective(workOrder);
			workOrderRelationMapper.updateWorkOrderRelation(workOrderRelation);

			workOrder = workOrderDao.selectById(workOrderId);
			jsonObject.put("name", "领取");
			recordHandleLog(workOrder, userId, jsonObject,new WriteFormTemplateInputDto());
			mqCommonUtil.pushToMsgTriggerQueue(workOrderId);
		} catch (Exception e) {
			log.error("工单领取异常:" + e);
			return new DbResponse(ResponseConstant.RES_FAIL_CODE, "工单领取失败");
		}
		return new DbResponse(ResponseConstant.RES_SUCCESS_CODE, "工单领取成功");
	}


	/**
	 * @return void
	 * @Author Donny_Dong
	 * @Description //TODO 获取合并工单信息
	 * @Date 21:10 2020/2/4
	 * @Param workOrderDto
	 **/
	@Override
	public DbResponse getCombineWorkOrderInfo(WorkOrderDto workOrderDto) {

		WorkOrderRelation workOrderRelation = getByWorkOrderId(workOrderDto.getWorkOrderId());
		String mergeBaseWorkOrderIds = workOrderRelation.getMergeBaseWorkOrderIds();

//		获取父工单合并
		if (FieldEnum.COMBINE_TYPE.getCode().equals(workOrderDto.getCombineType())) {
			PageHelper.startPage(workOrderDto.getPageNumber(), workOrderDto.getPageSize());
			List<WorkOrder> parentCombineWorkOrder = getParentCombineWorkOrder(workOrderDto.getWorkOrderId());
			PageInfo<WorkOrder> workOrderPageInfo = new PageInfo<>(parentCombineWorkOrder);
			return new DbResponse(ResponseConstant.RES_SUCCESS_CODE, ResponseConstant.SELECT_SUCCESS_MSG, parentCombineWorkOrder, workOrderPageInfo.getTotal());
		} else {
			//获取子工单合并
			PageHelper.startPage(workOrderDto.getPageNumber(), workOrderDto.getPageSize());
			List<WorkOrder> childrenCombineWorkOrder = getChildrenCombineWorkOrder(mergeBaseWorkOrderIds);
			PageInfo<WorkOrder> workOrderPageInfo = new PageInfo<>(childrenCombineWorkOrder);
			return new DbResponse(ResponseConstant.RES_SUCCESS_CODE, ResponseConstant.SELECT_SUCCESS_MSG, childrenCombineWorkOrder, workOrderPageInfo.getTotal());
		}


	}

	/**
	 * @Author: Donny_dong
	 * @Description: 获取子合并工单
	 * @Param:
	 * @return:
	 * @Date: 2020/4/30
	 */
	private List<WorkOrder> getChildrenCombineWorkOrder(String mergeBaseWorkOrderIds) {
		List<WorkOrder> workOrders = new ArrayList<>();
		if (!StringUtils.isEmpty(mergeBaseWorkOrderIds)) {
			List<String> ids = Arrays.asList(mergeBaseWorkOrderIds.split(","));
			workOrders = workOrderDao.selectWorkOrderListByIds(ids);
		}
		return workOrders;
	}

	/**
	 * @Author: Donny_dong
	 * @Description: 获取父类合并工单
	 * @Param:
	 * @return:
	 * @Date: 2020/4/30
	 */
	private List<WorkOrder> getParentCombineWorkOrder(String id) {
		HashMap<String, Object> hashMap = new HashMap<>(2);
		hashMap.put("workOrderId", id);
		List<WorkOrder> workOrders = new ArrayList<>();
		List<WorkOrderRelation> workOrderRelations = workOrderRelationMapper.selectWorkOrderRelations(hashMap);
		if (!CollectionUtils.isEmpty(workOrderRelations)) {
			List<String> collect = workOrderRelations.stream().map(workOrderRelation -> workOrderRelation.getWorkOrderId()).collect(Collectors.toList());
			workOrders = workOrderDao.selectWorkOrderListByIds(collect);
		}
		return workOrders;

	}


	/**
	 * @return void
	 * @Author Donny_Dong
	 * @Description //TODO 关注/取消关注工单
	 * @Date 13:02 2020/2/5
	 * @Param [jsonObject]
	 **/
	@Override
	public void monitorAndCancelWorkOrder(JSONObject jsonObject) {
		String ids = jsonObject.getString("id");
		String userId = jsonObject.getString("userId");
		String isMonitor = jsonObject.getString("isMonitor");
		List<String> idList = Arrays.asList(ids.split(","));
		Map<String, Object> hashMap = new HashMap<>(2);
		hashMap.put("workOrderIds", idList);
		List<WorkOrderRelation> workOrderRelations = workOrderRelationMapper.selectWorkOrderRelations(hashMap);
		List<WorkOrder> workOrders = workOrderDao.selectWorkOrderListByIds(idList);
		for (WorkOrderRelation workOrderRelation : workOrderRelations
		) {
			if (StringUtils.isEmpty(workOrderRelation.getWorkOrderMonitorId())) {
				workOrderRelation.setWorkOrderMonitorId(userId);
			} else {
				if (FieldEnum.IS_CANCLE.getCode().equals(isMonitor)) {
					String workOrderMonitorIds = workOrderRelation.getWorkOrderMonitorId();
					List<String> workOrderMonitorIdList = Arrays.asList(workOrderMonitorIds.split(","));
					List<String> collect = workOrderMonitorIdList.stream().filter(v -> !userId.equals(v))
							.collect(Collectors.toList());
					System.out.println(collect);
					String joinId = StringUtils.join(collect, ",");
					workOrderRelation.setWorkOrderMonitorId(joinId);
				} else {
					workOrderRelation.setWorkOrderMonitorId(workOrderRelation.getWorkOrderMonitorId() + "," + userId);
				}

			}
			workOrderRelationMapper.updateWorkOrderRelation(workOrderRelation);
		}
		recodeMonitorAndCancelLog(workOrders, isMonitor, userId);
	}

	/**
	 * @Author: Donny_dong
	 * @Description: 记录关注或取消关注的log
	 * @Param:
	 * @return:
	 * @Date: 2020/2/8
	 */
	private void recodeMonitorAndCancelLog(List<WorkOrder> workOrders, String isMonitor, String userId) {

		for (WorkOrder workOrder : workOrders
		) {
			JSONObject customField = workOrder.getCustomField();
			WorkOrderLog workOrderLog = new WorkOrderLog();
			workOrderLog.setBeforeTypeNodeId(workOrder.getCurrentWorkOrderNodeId());
			workOrderLog.setBeforeTypeNodeName(workOrder.getCurrentWorkOrderNodeName());
			workOrderLog.setWorkOrderId(workOrder.getId());
			workOrderLog.setWorkOrderNodeId(workOrder.getCurrentWorkOrderNodeId());
			workOrderLog.setTenantId(workOrder.getTenantId());
			int workOrderStatusId = workOrder.getStatusId();
			if (ConstantCode.Y.equals(isMonitor)) {
				workOrderLog.setLogType(WorkOrderLogType.MONITOR_WORK_ORDER_CODE);
			} else {
				workOrderLog.setLogType(WorkOrderLogType.CANCEL_WORK_ORDER_CODE);
			}
			workOrderLog.setWorkOrderStatusId(workOrderStatusId);
			workOrderLog.setLogCreaterId(userId);
			EwsUser ewsUser = ewsUserDao.selectById(userId);
			EwsDepartmentVo ewsDepartmentVo = ewsDepartmentDao.selectByPrimaryKeyAndTenantId(ewsUser.getDepartmentId(),ewsUser.getTenantId());
			workOrderLog.setLogCreateTime(new Date(System.currentTimeMillis()));
			workOrderLog.setLogCreaterName(ewsUser.getName());
			if (ewsDepartmentVo != null) {
				workOrderLog.setLogCreaterDept(ewsDepartmentVo.getName());
			}
			workOrderLogService.addSave(workOrderLog);
		}
	}
	/**
	 * TODO 工单退回上一步
	 * @author: victor_tang
	 * @createtime: 2020/5/12 10:18
	 * @param jsonObject 1
	 * @return: com.egoo.ews.service.utils.common.DbResponse
	 */
	@Override
	public DbResponse workOrderBackToLastStep(JSONObject jsonObject) {
		String workOrderId = jsonObject.getString("id");
		String userId = jsonObject.getString("userId");
		// 退回当前处理人
		boolean flag = backToCurrentHandle(jsonObject);
		if (flag) {
			return new DbResponse(ResponseConstant.RES_SUCCESS_CODE, "退回成功！");
		}
		EwsUser ewsUser = ewsUserDao.selectById(userId);
		WorkOrder workOrder = workOrderDao.selectById(workOrderId);
		String sourceNodeName = workOrder.getCurrentWorkOrderNodeName();
		String processInstanceId = workOrder.getProcessInstanceId();
		List<TaskForm> taskFormList = taskFormDao.selectByProcessInstanceId(processInstanceId);
		if (CollectionUtils.isEmpty(taskFormList)) {
			return new DbResponse(ResponseConstant.RES_FAIL_CODE,"初始节点，不能退回！");
		}
		TaskForm taskForm = taskFormList.get(taskFormList.size() - 1);
		String actRunningTaskId =
				ActTaskServiceUtil.getActiveTaskIdByProcessInstId(workOrder.getProcessInstanceId());
		if (taskFormList.size() == 1 && actRunningTaskId.equals(taskForm.getTaskId())) {
			return new DbResponse(ResponseConstant.RES_FAIL_CODE,
					"已经是退到初始节点，不能再退回了！");
		}
		//更新或者删除任务记录
		TaskForm backToTaskForm = updateOrDeleteTaskForm(taskFormList,
				workOrder, actRunningTaskId);

		// 根据最后任务处理信息，修改工单信息
		workOrder = handleWorkOrderFromWithdrawing(workOrder, backToTaskForm,ewsUser);

		//更新节点的工单分配方式的人
		updateNodeDistributeWay(taskForm.getNodeId(), workOrder.getCurrentHandlerId());

		//记录退回日志
		jsonObject.put("name", WorkOrderLogType.OVERRULED_CODE);
		workOrder.setLogContent(jsonObject.getString("logContent"));
		recordHandleLog(workOrder, userId, jsonObject,new WriteFormTemplateInputDto());
		log.info("工单退回后触发器发布的key为："+workOrderId);
		mqCommonUtil.pushToMsgTriggerQueue(workOrderId);
		mqCommonUtil.pushToMsgGeneralQueue(MsgNotifyType.FALL_BACK_NOTIFY,workOrder.getId());
		return new DbResponse(ResponseConstant.RES_SUCCESS_CODE, "退回成功！");
	}
	/**
	 * TODO 判断退回类别
	 *
	 * @param jsonObject 1
	 * @author: victor_tang
	 * @createtime: 2020/9/1 14:37
	 * @return: boolean
	 */
	private boolean backToCurrentHandle(JSONObject jsonObject) {
		String workOrderId = jsonObject.getString("id");
		List<WorkOrderLogVo> workOrderLogVos = workOrderLogDao.selectLogByWorkOrderId(workOrderId);
		if (CollectionUtils.isEmpty(workOrderLogVos)) {
			return false;
		}
		Integer indexLastReassign = null;
		for (int i = 0; i < workOrderLogVos.size(); i++) {
			if (WorkOrderLogType.REASSIGN_CODE.equals(workOrderLogVos.get(i).getLogType())) {
				indexLastReassign = i;
				break;
			}
		}
		if (indexLastReassign == null) {
			return false;
		}
		HashSet<String> nodeIdsSet = new HashSet<>();
		int backCount = 0;

		for (int i = 0; i < indexLastReassign + 1; i++) {
			WorkOrderLogVo workOrderLogVo = workOrderLogVos.get(i);
			nodeIdsSet.add(workOrderLogVo.getWorkOrderNodeId() + "");
			if (WorkOrderLogType.OVERRULED_CODE.equals(workOrderLogVo.getLogType())) {
				backCount += 1;
			}
		}
		if (nodeIdsSet.size() != 1) {
			return false;
		}
		if (backCount == 0) {
			// 首次退回工单当前处理人,获取最后一次改派的工单当前处理人信息
			jsonObject.put("content", workOrderLogVos.get(indexLastReassign).getContent());
			// 退回处理人
			backToHandle(jsonObject);
			return true;
		}
		// 再次退回当前处理人
		int reassignCount = 0;
		int indexAgainReassign = 0;
		for (int i = 0; i < workOrderLogVos.size(); i++) {
			if (WorkOrderLogType.REASSIGN_CODE.equals(workOrderLogVos.get(i).getLogType())) {
				reassignCount += 1;
			}
			if (reassignCount == backCount) {
				indexAgainReassign = i;
				break;
			}
			indexAgainReassign = i;
		}
		if (reassignCount != backCount) {
			return false;
		}

		HashSet<String> newNodeIdsSet = new HashSet<>();
		for (int i = 0; i < indexAgainReassign + 1; i++) {
			WorkOrderLogVo workOrderLogVo = workOrderLogVos.get(i);
			newNodeIdsSet.add(workOrderLogVo.getWorkOrderNodeId() + "");
		}
		if (newNodeIdsSet.size() != 1) {
			return false;
		}
		// 多次退回至改派人
		for (int i = 0; i < workOrderLogVos.size(); i++) {
			WorkOrderLogVo workOrderLogVo = workOrderLogVos.get(i);
			if (reassignCount==0&&WorkOrderLogType.REASSIGN_CODE.equals(workOrderLogVo.getLogType())) {
				jsonObject.put("content", workOrderLogVo.getContent());
				break;
			}
			if (WorkOrderLogType.REASSIGN_CODE.equals(workOrderLogVo.getLogType())) {
				reassignCount-=1;
			}
		}
		if (StringUtils.isEmpty(jsonObject.getString("content"))) {
			return false;
		}

		// 退回处理人
		backToHandle(jsonObject);
		return true;
	}
	/**
	 * TODO 退回处理人
	 * @author: victor_tang
	 * @createtime: 2020/9/1 16:14
	 * @param jsonObject 1
	 * @return: void
	 */
	private void backToHandle(JSONObject jsonObject) {
		String content = jsonObject.getString("content");
		String userId = jsonObject.getString("userId");
		String workOrderId = jsonObject.getString("id");
		if (content.isEmpty()) {
			log.error("改派操作记录的处理人变动信息为空，无法退回上一步操作人！");
			throw new RuntimeException("改派操作记录的处理人变动信息为空，无法退回上一步操作人！");
		}
		int i = content.lastIndexOf(ConstantCode.REASSIGN_CONTENT_TAG);
		String userIdstr = content.substring(i+ConstantCode.REASSIGN_CONTENT_TAG.length());
		List<String> userIds = Arrays.asList(userIdstr.split(","));
		Map<String, Object> stringObjectHashMap = new HashMap<>();
		stringObjectHashMap.put("userIds",userIds);
		List<EwsUser> ewsUsers = ewsUserDao.selectAllUserList(stringObjectHashMap);
		if (CollectionUtils.isEmpty(ewsUsers)) {
			log.error("根据用户id"+userIds+"获取的" + "改派操作记录的处理人信息为空！无法退回上一步操作人！");
			throw new RuntimeException("根据用户id"+userIds+"获取的" +
					"改派操作记录的处理人信息为空！，无法退回上一步操作人！");
		}
		WorkOrder workOrder = workOrderDao.selectById(workOrderId);
		workOrder.setId(workOrderId);
		workOrder.setCurrentHandlerId(userIdstr);
		workOrder.setCurrentHandlerName(ewsUsers.stream().map(ewsUser -> ewsUser.getName()).collect(Collectors.joining(",")));
		workOrder.setLastUpdateTime(new Timestamp(System.currentTimeMillis()));
		workOrder.setLastUserId(userId);
		EwsUser ewsUser = ewsUserDao.selectById(userId);
		workOrder.setLastUserName(ewsUser==null?null:ewsUser.getName());
		workOrderDao.updateWorkOrder(workOrder);

		//记录退回日志
		String button = jsonObject.getString("button");
		String reason = null;
		if (WorkOrderLogType.OVERRULED_NAME.equals(button)) {
			jsonObject.put("name", WorkOrderLogType.OVERRULED_CODE);
			reason = jsonObject.getString("reason");
		}else {
			jsonObject.put("name",WorkOrderLogType.WITHDRAW_NAME);
			reason = jsonObject.getString("logContent");
		}

		workOrder.setLogContent(workOrder.getCurrentWorkOrderNodeName() + " ==> " + workOrder.getCurrentWorkOrderNodeName() + ",处理原因：" + reason);
		recordHandleLog(workOrder, userId, jsonObject,null);
	}
	/**
	 * TODO 更新或者删除任务记录
	 *
	 * @param taskFormList 1
	 * @param workOrder    2
	 * @author: victor_tang
	 * @createtime: 2020/5/11 13:58
	 * @return: com.egoo.ews.service.vo.TaskForm
	 */
	private TaskForm updateOrDeleteTaskForm(List<TaskForm> taskFormList,
											WorkOrder workOrder, String actRunningTaskId) {
		TaskForm taskForm = taskFormList.get(taskFormList.size() - 1);
		if (actRunningTaskId.equals(taskForm.getTaskId())) {
			// 连续退回，删除最后一条任务记录
			taskFormDao.deleteByTaskId(actRunningTaskId);
			if (taskFormList.size()>1) {
				taskForm = taskFormList.get(taskFormList.size() - 2);
			}
		}
		// 更新任务信息
		return updateWithdrawTaskForm(taskForm, workOrder);
	}
	/**
	 * TODO 撤回工单
	 * @author: victor_tang
	 * @createtime: 2020/5/12 10:18
	 * @param jsonObject 1
	 * @return: com.egoo.ews.service.utils.common.DbResponse
	 */
	@Override
	public DbResponse withdrawWorkOrder(JSONObject jsonObject) {
		String workOrderId = jsonObject.getString("id");
		String userId = jsonObject.getString("userId");
		boolean flag = backToCurrentHandle(jsonObject);
		if (flag) {
			return new DbResponse(ResponseConstant.RES_SUCCESS_CODE, "撤回成功！");
		}
		EwsUser ewsUser = ewsUserDao.selectById(userId);
		WorkOrder workOrder = workOrderDao.selectById(workOrderId);
		List<WorkOrderLogVo> workOrderLogVos = workOrderLogDao.selectLogByWorkOrderId(workOrderId);
		List<Long> overruledList = workOrderLogVos.stream().filter(workOrderLogVo -> WorkOrderLogType.OVERRULED_CODE.equals(workOrderLogVo.getLogType())).map(workOrderLogVo -> workOrderLogVo.getWorkOrderNodeId()).collect(Collectors.toList());
		List<Long> nodeIds = null;
		if (!CollectionUtils.isEmpty(overruledList)) {
			nodeIds = workOrderLogVos.stream().filter(workOrderLogVo -> !overruledList.contains(workOrderLogVo.getWorkOrderNodeId())).map(workOrderLogVo -> workOrderLogVo.getWorkOrderNodeId()).collect(Collectors.toList());
		}else {
			nodeIds = workOrderLogVos.stream().map(workOrderLogVo -> workOrderLogVo.getWorkOrderNodeId()).collect(Collectors.toList());
		}
		if (nodeIds.contains(workOrder.getCurrentWorkOrderNodeId())){
			return new DbResponse(ResponseConstant.RES_FAIL_CODE,"该工单已被处理,不能撤回");
		}
		String processInstanceId = workOrder.getProcessInstanceId();
		List<TaskForm> taskFormList = taskFormDao.selectByProcessInstanceId(processInstanceId);
		TaskForm taskForm = taskFormList.get(taskFormList.size() - 1);
		// 根据最后任务处理信息，修改工单信息
		workOrder = handleWorkOrderFromWithdrawing(workOrder, taskForm,ewsUser);
		//更新撤回工单的任务
		updateWithdrawTaskForm(taskForm, workOrder);
		//更新节点的工单分配方式的人
		updateNodeDistributeWay(taskForm.getNodeId(), workOrder.getCurrentHandlerId());
		//记录撤回Log
		jsonObject.put("name", WorkOrderLogType.WITHDRAW_CODE);
		workOrder.setLogContent(jsonObject.getString("logContent"));
		recordHandleLog(workOrder, userId, jsonObject,new WriteFormTemplateInputDto());
		return new DbResponse(ResponseConstant.RES_SUCCESS_CODE, "撤回成功！");
	}
	/**
	 * TODO 更新撤回工单的任务
	 *
	 * @param taskForm  1
	 * @param workOrder 2
	 * @author: victor_tang
	 * @createtime: 2020/5/11 13:45
	 * @return: void
	 */
	private TaskForm updateWithdrawTaskForm(TaskForm taskForm, WorkOrder workOrder) {
		Long previousNodeId = taskForm.getNodeId();
		String nodeName = taskForm.getNodeName();
		ActCommonUtils.arbitraryJump(nodeName + previousNodeId,
				workOrder.getProcessInstanceId());
		String taskIdOfWithdraw =
				ActTaskServiceUtil.getActiveTaskIdByProcessInstId(workOrder.getProcessInstanceId());
		List<TaskForm> taskForms = taskFormDao.selectByProcessInstanceId(workOrder.getProcessInstanceId());
		Optional<TaskForm> max = taskForms.stream().max(Comparator.comparingInt(TaskForm::getId));
		Integer maxId = max.get().getId();
		log.info("最大任务id:"+maxId);
		taskForm.setTaskId(taskIdOfWithdraw);
		JSONObject nodeInfo = taskForm.getNodeInfo();
		nodeInfo.put("withdraw", ConstantCode.Y);
		nodeInfo.put("taskSign","unNormal");
		taskForm.setNodeInfo(nodeInfo);
		taskForm.setId(maxId);
		taskFormDao.updateByProcessInstanceIdAndNodeId(taskForm);
		return taskForm;
	}
	/**
	 * TODO 判断工单退回按钮是否
	 * @author: victor_tang
	 * @createtime: 2020/5/11 16:03
	 * @param workOrder 1
	 * @return: java.lang.Boolean
	 */
	private Boolean getIsViewBackToLastStep(WorkOrder workOrder) {
		List<TaskForm> taskForms = taskFormDao.selectByProcessInstanceId(workOrder.getProcessInstanceId());
		if (CollectionUtils.isEmpty(taskForms)) {
			// 没有处理记录不可退回
			return false;
		}
		if (taskForms.size()>1) {
			// 大于一条处理记录可退回
			return true;
		}
		// 一条处理记录时，节点为初始节点时不能再退回
		TaskForm taskForm = taskForms.get(0);
		String currentTaskId =
				ActTaskServiceUtil.getActiveTaskIdByProcessInstId(workOrder.getProcessInstanceId());
		if (taskForm.getTaskId().equals(currentTaskId)) {
			return false;
		}
		return true;
	}
	/**
	 * @Author: Donny_dong
	 * @Description: 更新节点的工单分配方式的人
	 * @Param:
	 * @return:
	 * @Date: 2020/2/13
	 */
	private void updateNodeDistributeWay(Long previousNodeId, String userId) {
		WorkOrderTypeNodeVo workOrderNode = workOrderTypeNodeDao.getNodeByWorkOrderNodeId(previousNodeId);
		if (WorkOrderDistributionWay.SEQUENCE_DISTRIBUTION.equals(workOrderNode.getDistributeWay())) {
			workOrderNode.setLastDistributeUserId(userId);
		}
		workOrderTypeNodeDao.updateByPrimaryKeySelective(workOrderNode);
	}

	/**
	 * TODO 处理撤回后的工单及任务信息
	 *
	 * @param workOrder 1
	 * @param taskForm  2
	 * @author: victor_tang
	 * @createtime: 2020/5/11 14:34
	 * @return: com.egoo.ews.service.vo.WorkOrder
	 */
	private WorkOrder handleWorkOrderFromWithdrawing(WorkOrder workOrder,
													 TaskForm taskForm,
													 EwsUser ewsUser) {
		Long previousNodeId = taskForm.getNodeId();
		String nodeName = taskForm.getNodeName();
		List<String> hisHandleIds = Arrays.asList(workOrder.getHistoryHandlerId().split(","));
		String historyHandleId = hisHandleIds.stream().filter(s -> hisHandleIds.indexOf(s) != hisHandleIds.size() - 1).collect(Collectors.joining(","));
		List<String> hisHandleNames = Arrays.asList(workOrder.getHistoryHandlerName().split(","));
		String historyHandleName = hisHandleNames.stream().filter(s -> hisHandleNames.indexOf(s) != hisHandleNames.size() - 1).collect(Collectors.joining(","));
		// 设置退回后工单当前处理人
		workOrder.setCurrentHandlerId(hisHandleIds.get(hisHandleIds.size() - 1));
		workOrder.setCurrentHandlerName(hisHandleNames.get(hisHandleNames.size() - 1));
		// 剔除最后一位历史处理人
		workOrder.setHistoryHandlerId(historyHandleId);
		workOrder.setHistoryHandlerName(historyHandleName);
		// 设置退回后节点
		workOrder.setCurrentWorkOrderNodeId(previousNodeId);
		workOrder.setCurrentWorkOrderNodeName(nodeName);

		workOrder.setLastUpdateTime(new Timestamp(System.currentTimeMillis()));
		workOrder.setLastUserId(ewsUser.getId());
		workOrder.setLastUserName(ewsUser.getName());
		//获取节点信息
		JSONObject nodeInfo = taskForm.getNodeInfo();
		Integer nodeStatus = nodeInfo.getInteger("nodeStatus");
		workOrder.setStatusId(nodeStatus);
		workOrderDao.updateWorkOrder(workOrder);
		return workOrder;
	}

	/**
	 * @Author: Donny_dong
	 * @Description: 更新客户唯一标识
	 * @Param:
	 * @return:
	 * @Date: 2020/3/13
	 */
	@Override
	public DbResponse updateCustomIdentify(JSONObject jsonObject) {

		try {
			workOrderDao.updateCustomIdentify(JSONObject.toJavaObject(jsonObject, Map.class));
		} catch (Exception e) {
			log.error("更新客户唯一标识异常" + e);
			return new DbResponse(ResponseConstant.RES_FAIL_CODE, "更新客户唯一标识异常" + e);
		}
		return new DbResponse(ResponseConstant.RES_SUCCESS_CODE, "更新成功");
	}

	/**
	 * TODO 根据sessionId获取工单信息列表
	 *
	 * @param sessionId 1
	 * @author: victor_tang
	 * @createtime: 2020/3/26 14:52
	 * @return: com.egoo.ews.service.utils.DBResponse
	 */
	@Override
	public DbResponse getworkOrderInfoBySessionId(String sessionId, String userId) {
		log.info("传入的sessionId为：" + sessionId);
		List<String> sessionIds = Arrays.asList(sessionId.split(","));
		Map<String, Object> searchMap = new HashMap<>(2);
		searchMap.put("sessionIds", sessionIds);
		List<WorkOrder> workOrders = workOrderDao.selectWorkOrderInfoBySessionId(searchMap);
		log.info("根据sessionId获取工单信息:" + workOrders);
		// 处理翻译工单列表页面所需展示得字段和标识
		List<WorkOrderListOutputDto> dataList = handleWorkListData(workOrders, userId);
		long count = dataList.size();
		return new DbResponse(ResponseConstant.RES_SUCCESS_CODE, ResponseConstant.SELECT_SUCCESS_MSG, dataList,count);
	}

	/**
	 * @Author: Donny_dong
	 * @Description: 组装工单转出参数
	 * @Param:
	 * @return:
	 * @Date: 2020/5/11
	 */
	private JSONObject assembleExternalParam(WorkOrderDto workOrderDto, JSONObject jsonObject) {
		JSONObject opration = workOrderDto.getOpration();
		Long workOrderTypeId = workOrderDto.getWorkOrderTypeId();
		Long sourceRef = opration.getLong("sourceRef");
		Map<String, Object> hashMap = new HashMap<>();
		hashMap.put("tenantId",workOrderDto.getTenantId());
		hashMap.put("processInstanceId",workOrderDto.getProcessInstanceId());
		hashMap.put("nodeId",sourceRef);
		TaskForm taskForm = taskFormDao.selectDynamic(hashMap);
		JSONObject modelValue = taskForm.getContent().getJSONObject("modelValue");
		String targetRef = opration.getString("targetRef");
		List<WorkOrderFieldReflect> workOrderFieldReflects = workOrderFieldReflectDao.selectByWorkOrderTypeId(workOrderTypeId.toString(), workOrderDto.getTenantId(),targetRef);
		if (CollectionUtils.isEmpty(workOrderFieldReflects)){
			log.info("字段映射为空,不能匹配转出参数"+workOrderFieldReflects);
			return jsonObject;
		}
		JSONObject body = new JSONObject();
		for (WorkOrderFieldReflect workOrderFieldReflect :
				workOrderFieldReflects) {
			String externalFieldName = workOrderFieldReflect.getExternalFieldName();
			String innerFieldName = workOrderFieldReflect.getInnerFieldName();
			Map map = JSON.parseObject(modelValue.toJSONString(), Map.class);
			for (Object o:map.keySet()
				 ) {

				if (innerFieldName.equals(o)) {
					if (StringUtils.isEmpty(externalFieldName)) {
						body.put(innerFieldName, modelValue.get(o));
					}else {
						body.put(externalFieldName,modelValue.get(o));
					}
				}
			}
		}
		jsonObject.put("body",body);
		return jsonObject;
	}

	/**
	 * @Author: Donny_dong
	 * @Description: 转入工单
	 * @Param:
	 * @return:
	 * @Date: 2020/5/12
	 */
	@Override
	public DbResponse externalFlowInto(WorkOrderDto workOrderDto) {
		String workOrderId = workOrderDto.getWorkOrderId();
		Long workOrderTypeId = workOrderDto.getWorkOrderTypeId();
//		Long currentWorkOrderNodeId = workOrderDto.getCurrentWorkOrderNodeId();
		WorkOrder workOrder = workOrderDao.selectById(workOrderId);
		WorkOrderTypeNodeVo workOrderTypeNodeVo = workOrderTypeNodeDao.selectById(workOrder.getCurrentWorkOrderNodeId());

		flowIntoTask(workOrder, workOrderDto, workOrderTypeNodeVo);
		workOrder = flowIntoHandle(workOrderDto, workOrder, workOrderTypeNodeVo);

		// activiti的任意跳转
		ActCommonUtils.arbitraryJump(workOrder.getCurrentWorkOrderNodeName() + workOrder.getCurrentWorkOrderNodeId(), workOrder.getProcessInstanceId());
		workOrderDao.updateWorkOrder(workOrder);
		JSONObject opration = new JSONObject();
		opration.put("name", FieldEnum.FLOW_INTO.getMessage());
		recordHandleLog(workOrder, "", opration,new WriteFormTemplateInputDto());
		return new DbResponse(ResponseConstant.RES_SUCCESS_CODE, "转入成功！");
	}

	/**
	 * @Author: Donny_dong
	 * @Description: 转入任务记录
	 * @Param:
	 * @return:
	 * @Date: 2020/5/13
	 */
	private void flowIntoTask(WorkOrder workOrder, WorkOrderDto workOrderDto, WorkOrderTypeNodeVo workOrderTypeNodeVo) {
		JSONObject externalFlowInfo = workOrderDto.getExternalFlowInfo();
		String externalUserId = externalFlowInfo.getString("externalUserId");
		String externalUserName = externalFlowInfo.getString("externalUserName");
		JSONArray externalFlowRecode = externalFlowInfo.getJSONArray("externalFlowRecode");
		String processInstanceId = workOrder.getProcessInstanceId();
		JSONObject nodeVoContent = workOrderTypeNodeVo.getContent();
		String taskId =
				ActTaskServiceUtil.getActiveTaskIdByProcessInstId(processInstanceId);
		TaskForm taskForm = new TaskForm();
		JSONObject content = new JSONObject();
		JSONObject nodeInfo = new JSONObject();
		content.put("list", externalFlowRecode);
		nodeInfo.put("withdraw", ConstantCode.N);
		nodeInfo.put("nodeStatus", nodeVoContent.getString("statusId"));
		taskForm.setTaskId(taskId);
		taskForm.setProcessInstanceId(processInstanceId);
		taskForm.setHandlerId(externalUserId);
		taskForm.setHandlerName(externalUserName);
		taskForm.setNodeId(workOrderTypeNodeVo.getId());
		taskForm.setNodeName(workOrderTypeNodeVo.getName());
		taskForm.setSubmitTime(new Timestamp(System.currentTimeMillis()));
		taskForm.setContent(content);
		taskForm.setNodeInfo(nodeInfo);
		taskForm.setTenantId(workOrder.getTenantId());
		taskFormDao.create(taskForm);
	}

	/**
	 * @Author: Donny_dong
	 * @Description: 转入处理
	 * @Param:
	 * @return:
	 * @Date: 2020/5/12
	 */
	private WorkOrder flowIntoHandle(WorkOrderDto workOrderDto, WorkOrder workOrder, WorkOrderTypeNodeVo workOrderTypeNodeVo) {
		Timestamp time = new Timestamp(System.currentTimeMillis());
		JSONObject nodeVoContent = workOrderTypeNodeVo.getContent();
		Long targetRef = nodeVoContent.getLong("afterFlowNode");
//		targetRef=1589529354756L;
		Integer statusId = nodeVoContent.getInteger("flowInStatus");
		workOrder = flowIntoHandler(targetRef, workOrder);
		workOrder.setStatusId(statusId);
		workOrder.setLastUpdateTime(time);
		//用于记录转入人信息，为撤回做标记
		workOrder.setHistoryHandlerId(workOrder.getHistoryHandlerId()+ FlowInto.FLOW_INTO_ID);
		workOrder.setHistoryHandlerName(workOrder.getHistoryHandlerName()+FlowInto.FLOW_INTO_NAME);
		return workOrder;
	}

	/**
	 * @Author: Donny_dong
	 * @Description: 转入后处理人设置
	 * @Param:
	 * @return:
	 * @Date: 2020/5/12
	 */
	private WorkOrder flowIntoHandler(Long targetRef, WorkOrder workOrder) {
		WorkOrderTypeNodeVo workOrderTypeNodeVo = workOrderTypeNodeDao.selectById(targetRef);
		workOrder.setCurrentWorkOrderNodeId(workOrderTypeNodeVo.getId());
		workOrder.setCurrentWorkOrderNodeName(workOrderTypeNodeVo.getName());
		return this.setTiaoZhuanWorkOrderHandlePersonInfo(workOrder, workOrderTypeNodeVo);
	}

	@Override
	public DbResponse getAllBaseBussinessField(String workOrderTypeId,String tenantId) {
		try {
			List<TableHeadField> baseFields = getBaseField();
			ArrayList<FieldInfo> fieldInfos = new ArrayList<>();
			for (TableHeadField tableHeadField:baseFields) {
				String prop = tableHeadField.getProp();
				String label = tableHeadField.getLabel();
				String type = tableHeadField.getType();
				String belongToTable = tableHeadField.getBelongToTable();
				boolean slot = ConstantCode.STATUS_NOMAL.equals(tableHeadField.getSlot()) ? true : false;
				FieldInfo fieldInfo = new FieldInfo(prop, label, type, slot,belongToTable);
				fieldInfos.add(fieldInfo);
			}
			WorkOrderTypeVo workOrderTypeVo = workOrderTypeDao.selectById(Long.valueOf(workOrderTypeId));
			HashMap<String, Object> map = new HashMap<>(4);
			map.put("workOrderTypeId",workOrderTypeId);
			map.put("maxVersion",workOrderTypeVo.getMaxVersion());
			map.put("tenantId",tenantId);
			List<WorkOrderTypeNodeVo> workOrderTypeNodeVos = workOrderTypeNodeDao.selectNodeListByCondition(map);
	//			String formKeySign = workOrderTypeDao.selectById(Long.valueOf(workOrderTypeId)).getContent().getJSONObject("newworkordernodeInfo").getString("formKeySign");
			List<FieldInfo>	fieldInfoList = getNodeFormTemplateField(fieldInfos, workOrderTypeNodeVos);
			for (int i = 0; i <fieldInfoList.size() ; i++) {
				fieldInfoList.get(i).setOrder(i);
			}
			return new DbResponse(ResponseConstant.RES_SUCCESS_CODE,ResponseConstant.SELECT_SUCCESS_MSG,fieldInfoList);
		} catch (Exception e) {
			log.error("基础字段表头获取异常:"+e);
			return new DbResponse(ResponseConstant.RES_FAIL_CODE,ResponseConstant.SELECT_FAIL_MSG,null);
		}
	}

	/**
	 * @Author: Donny_dong
	 * @Description: 获取基础字段
	 * @Param:
	 * @return:
	 * @Date: 2020/7/28
	 */
	private List<TableHeadField> getBaseField() {
		TableHeadFieldDto tableHeadFieldDto = new TableHeadFieldDto();
		tableHeadFieldDto.setWorkOrderFilterMenuId(1L);
		List<TableHeadField> tableHeadFields = tableHeadFieldMapper.selectByFilterId(tableHeadFieldDto);
		return tableHeadFields ;
	}

	/**
	 * @Author: Donny_dong
	 * @Description: 获取节点模板中的字段
	 * @Param:
	 * @return:
	 * @Date: 2020/6/9
	 */
	private List<FieldInfo> getNodeFormTemplateField(ArrayList<FieldInfo> fieldInfos, List<WorkOrderTypeNodeVo> workOrderTypeNodeVos) {
		if (CollectionUtils.isEmpty(workOrderTypeNodeVos)){
			return fieldInfos;
		}
		for (WorkOrderTypeNodeVo workOrderTypeNodeVo:
				workOrderTypeNodeVos) {
			String formKeySign = workOrderTypeNodeVo.getFormKeySign();
			if ("1".equals(formKeySign)){
				continue;
			}
			JSONObject formTempalteContent = workOrderTypeNodeVo.getFormTempalteContent();
			JSONArray listTemplate = formTempalteContent.getJSONArray("list");
			for (int i = 0; i <listTemplate.size(); i++) {
				JSONObject jsonObjectTemplate = listTemplate.getJSONObject(i);
				String model = jsonObjectTemplate.getString("model");
				String name = jsonObjectTemplate.getString("name");
				String type = jsonObjectTemplate.getString("type");
				if (FormTemplateType.DATE.equals(type)){
					type = model;
				}
				FieldInfo fieldInfo = new FieldInfo();
				if(type.equals("grid")){
//					continue;
					fieldInfos = getGridField(jsonObjectTemplate,fieldInfos);
				}else {

					fieldInfo.setProp(model);
					fieldInfo.setLabel(name);
					fieldInfo.setType(type);
					fieldInfo.setSlot(false);
					fieldInfo.setBelongToTable(BelongToTable.WORK_ORDER_CUSTOMFIELD);
					fieldInfos.add(fieldInfo);
				}

			}
		}
		List<FieldInfo> collect = fieldInfos.stream().distinct().collect(Collectors.toList());
		return collect;
	}

	/**
	 * @Author: Donny_dong
	 * @Description: 获取栅格中的字段
	 * @Param:
	 * @return:
	 * @Date: 2020/8/6
	 */
	private ArrayList<FieldInfo> getGridField(JSONObject jsonObjectTemplate,ArrayList<FieldInfo> fieldInfos) {
		JSONArray columns = jsonObjectTemplate.getJSONArray("columns");
		for (int i = 0; i <columns.size() ; i++) {
			JSONObject jsonObject = columns.getJSONObject(i);
			JSONArray list = jsonObject.getJSONArray("list");
			for (int j = 0; j < list.size(); j++) {
				JSONObject jsonObject1 = list.getJSONObject(j);
				String model = jsonObject1.getString("model");
				String name = jsonObject1.getString("name");
				String type = jsonObject1.getString("type");
				if(type.equals("grid")){
					continue;
				}else {
					FieldInfo fieldInfo = new FieldInfo();
					fieldInfo.setProp(model);
					fieldInfo.setLabel(name);
					fieldInfo.setType(type);
					fieldInfo.setSlot(false);
					fieldInfos.add(fieldInfo);
				}
			}
		}
		return fieldInfos;
	}

	/**
	 * @Author: Donny_dong
	 * @Description: 获取高级筛选条件
	 * @Param:
	 * @return:
	 * @Date: 2020/9/1
	 */
	@Override
	public DbResponse advancedFilterData(String workOrderFilterMenuIdStr,String tenantId) {
		TableHeadFieldDto tableHeadFieldDto = new TableHeadFieldDto();
		Long workOrderFilterMenuId = Long.valueOf(workOrderFilterMenuIdStr);
		tableHeadFieldDto.setWorkOrderFilterMenuId(workOrderFilterMenuId);
		ArrayList<TableHeadFieldVo> tableHeadFieldVos = headFieldService.select(tableHeadFieldDto);
		for (TableHeadFieldVo tableHeadFieldVo:tableHeadFieldVos
			 ) {
			tableHeadFieldVo = setAllDicData(tableHeadFieldVo,tenantId);
			if (workOrderFilterMenuId ==ConstantCode.SysFilter.ALL_FILTER_ID || workOrderFilterMenuId == ConstantCode.SysFilter.CREATE_FILTER_ID
					|| workOrderFilterMenuId == ConstantCode.SysFilter.EDIT_FILTER_ID || workOrderFilterMenuId == ConstantCode.SysFilter.MONITOR_FILTER_ID
					|| workOrderFilterMenuId == ConstantCode.SysFilter.WAIT_HANDLE_FILTER_ID || workOrderFilterMenuId ==ConstantCode.SysFilter.FINISHED_FILTER_ID
					|| workOrderFilterMenuId == ConstantCode.SysFilter.FROM_DEPT_FILTER_ID){
				continue;
			}
			tableHeadFieldVo.setHide(false);
		}
		return new DbResponse(ResponseConstant.RES_SUCCESS_CODE,ResponseConstant.SELECT_SUCCESS_MSG,tableHeadFieldVos);
	}
	/**
	 * @Author: Donny_dong
	 * @Description: 获取列表查询的所有下拉和级联数据源
	 * @Param:
	 * @return:
	 * @Date: 2020/9/1
	 */
	private TableHeadFieldVo setAllDicData(TableHeadFieldVo tableHeadFieldVo,String tenantId) {
		String code = tableHeadFieldVo.getProp();
		String fieldType = tableHeadFieldVo.getType();
		String belongToTable = tableHeadFieldVo.getBelongToTable();
		String id = tableHeadFieldVo.getId();
		JSONArray dicData = null;
		if (BelongToTable.WORK_ORDER.equals(belongToTable)||BelongToTable.WORK_ORDER_RELATION.equals(belongToTable)) {
			dicData = getSysData(code, tenantId);

		}else {
			if (ConstantCode.FormTemplateType.SELECT.equals(fieldType)
					||ConstantCode.FormTemplateType.CASCADER.equals(fieldType)) {
				dicData = customFieldService.selectByCode(code, tenantId);
			}
		}
		if(FormTemplateType.DATE_TIME_RANGE.equals(fieldType) || FormTemplateType.DATE_RANGE.equals(fieldType)){
			tableHeadFieldVo.setValueFormat("yyyy-MM-dd HH:mm:ss");
		}
		tableHeadFieldVo.setDicData(dicData);
		return tableHeadFieldVo;
	}

	/**
	 * @Author: Donny_dong
	 * @Description: 获取系统下拉和级联数据源
	 * @Param:
	 * @return:
	 * @Date: 2020/9/1
	 */
	private JSONArray getSysData(String code,String tenantId) {
		JSONArray jsonArray =null;
		if (WorkOrderBaseFieldMeanig.STATUS_FIELD.equals(code)){
			List<WorkOrderStatusDataVo> workOrderStatusDataVos = workOrderStatusDao.selectAllStatuss(tenantId);
			 jsonArray = JSONArray.parseArray(JSON.toJSONString(workOrderStatusDataVos));

		}else if (WorkOrderBaseFieldMeanig.WORK_ORDER_TYPE_FIELD.equals(code)){
			List<InteractiveDataVo> interactiveDataVos = workOrderTypeDao.selectAllWorkOrderTypeName(tenantId);
			jsonArray = JSONArray.parseArray(JSON.toJSONString(interactiveDataVos));
		}
		return jsonArray;
	}


	@Override
	public DbResponse alterWorkOderStatus(Map<String, Object> map) {

		try {
			Integer integer = workOrderDao.updateWorkOrderStatus(map);
			log.info("状态修改结果："+integer);
			return new DbResponse(ResponseConstant.RES_SUCCESS_CODE,ResponseConstant.UPDATE_SUCCESS_MSG);
		} catch (Exception e) {
			log.info("浙能修改工单状态异常"+e);
			return new DbResponse(ResponseConstant.RES_FAIL_CODE,ResponseConstant.UPDATE_SUCCESS_MSG);
		}
	}
}
